我有一个例子:
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
Run Code Online (Sandbox Code Playgroud)
如果我改变了closure这样的话:
var closure = { [weak a] in
a = Animal()
a?.stamina = 10
}
Run Code Online (Sandbox Code Playgroud)
然后它打印出这样的东西:
a.stamina // 0
a.increaseStamina()
a.stamina // 1
closure()
a.stamina // 1
Run Code Online (Sandbox Code Playgroud)
为什么最后一行不同?
捕获列表中的所有条目都在闭包中创建一个局部变量.它使用外部上下文中具有相同名称的变量值进行初始化,但可以单独修改.
在你的情况下
var closure = { [weak a] in
a = Animal()
a?.stamina = 10
}
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
如果省略捕获列表,则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
Run Code Online (Sandbox Code Playgroud)
有关更多信息和详细信息,请参阅Swift参考中的"捕获列表"(感谢@Arthur提供链接).
| 归档时间: |
|
| 查看次数: |
2796 次 |
| 最近记录: |