【发布时间】:2020-11-04 14:11:09
【问题描述】:
我知道 [weak self] 和 [unowned self] 但我不知道 [self]。
它的作用如何?
[self] = [unowned self] 要么 [self] = 强引用
【问题讨论】:
标签: swift self self-reference
我知道 [weak self] 和 [unowned self] 但我不知道 [self]。
它的作用如何?
[self] = [unowned self] 要么 [self] = 强引用
【问题讨论】:
标签: swift self self-reference
通过捕获子句捕获变量:
var closure = { [x] in x.doSomething() }
将创建对 x 在闭包创建时所引用的值的强捕获。见最后的例子。
如果你不使用像in这样的捕获子句
var closure = { x.doSomething() }
这将创建一个对 x 在闭包执行时引用的值的强引用。
话虽如此,捕获 [self] 会创建一个强引用,但完全没有必要,除非您预计 self 会在某个时间点发生变化(这将是非常不寻常的)。
class ValueClass {
var value:String
init (_ v:String) { value = v }
func info() { print("\(value)") }
deinit { print ("deinit: \(value)") }
}
if (1==1) {
print (">> No capture clause")
var a:ValueClass? = ValueClass("a")
let closure = { a != nil ? a!.info() : print("a is nil") }
a = ValueClass("changed a") // "deinit: a"
closure() // "a is nil"
print ("<< done")
}// "deinit: changed a"
print ("------------------------------")
if (1==1) {
print (">> strong capture clause")
var b:ValueClass? = ValueClass("b")
let closure = { [b] in b != nil ? b!.info() : print("b is nil") }
b = ValueClass("changed b")
closure() // "b"
print ("<< done")
} // "deinit: b"; "deinit: changed b"
print ("------------------------------")
if (1==1) {
print (">> weak capture clause")
var c:ValueClass? = ValueClass("c")
let closure = { [weak c] in c != nil ? c!.info() : print("c is nil") }
c = ValueClass("changed c") // "deinit: c"
closure() // "c is nil"
print ("<< done")
} // "deinit: changed c"
print ("------------------------------")
if (1==1) {
print (">> unowned capture clause")
var d:ValueClass? = ValueClass("d")
let closure = { [unowned d] in d != nil ? d!.info() : print("d is nil") }
d = ValueClass("changed d") // "deinit: d"
closure() // error: Execution was interrupted, reason: signal SIGABRT.
print ("<< done")
}
输出是
>> No capture clause
deinit: a
changed a
<< done
deinit: changed a
------------------------------
>> strong capture clause
b
<< done
deinit: b
deinit: changed b
------------------------------
>> weak capture clause
deinit: c
c is nil
<< done
deinit: changed c
------------------------------
>> unowned capture clause
deinit: d
(CRASH)
如你所见,
[b] 时,会创建并输出对“b”的强引用,因为b 在创建时是“b”[weak c] 时,会创建对“c”的弱引用;由于 c 已更改为“changed c”,旧的“c”被取消,因此捕获为 nill,输出为“c is nil”[unowned c] 时相同,只是您的程序崩溃了【讨论】: