我有一个例子:
class Animal {
var stamina = 0
func increaseStamina() {
stamina += 1
}
}
var a = Animal()
var closure = { [weak a] in
a?.stamina = 10
}
a.stamina // 0
a.increaseStamina()
a.stamina // 1
closure()
a.stamina // 10
如果我这样更改
closure
:var closure = { [weak a] in
a = Animal()
a?.stamina = 10
}
然后它会打印出这样的内容:
a.stamina // 0
a.increaseStamina()
a.stamina // 1
closure()
a.stamina // 1
为什么最后一行不同?
最佳答案
捕获列表中的所有条目都会在
关闭。用变量的值初始化
在外部上下文中具有相同的名称,但可以修改
独立地。
在你的情况下
var closure = { [weak a] in
a = Animal()
a?.stamina = 10
}
闭包内部的
a
使用对之前创建的Animal
对象的弱引用进行初始化,但它与外部a
变量无关。 a = Animal()
创建一个新实例并分配对该局部变量
a
的引用。因为这是一个较弱的引用,该对象将立即释放(您可以验证是否
通过在闭包中添加
print(a)
来实现)。外部变量a
仍然引用原始对象:print(a.stamina) // 0
a.increaseStamina()
print(a.stamina) // 1
print(ObjectIdentifier(a)) // ObjectIdentifier(0x0000000100a03060)
closure()
print(ObjectIdentifier(a)) // ObjectIdentifier(0x0000000100a03060)
print(a.stamina) // 1
如果省略捕获列表,则在闭包内添加
a
在闭包之外引用相同的变量,并可以在闭包内部分配一个新实例:
var a = Animal()
var closure = {
a = Animal()
a.stamina = 10
}
print(a.stamina) // 0
a.increaseStamina()
print(a.stamina) // 1
print(ObjectIdentifier(a)) // ObjectIdentifier(0x0000000100b06ac0)
closure()
print(ObjectIdentifier(a)) // ObjectIdentifier(0x0000000100e00070)
print(a.stamina) // 10
有关更多信息和详细信息,请参见Swift引用资料中的"Capture Lists"(感谢@Arthur提供的
链接)。
关于ios - 在Swift中捕获列表,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39465726/