我有一个例子:
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
为什么最后一行不同?
答案 0 :(得分:6)
捕获列表中的所有条目都在中创建本地变量 关闭。它用变量的值初始化 在外部上下文中具有相同的名称,但可以进行修改 独立地
在你的情况下
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提供 链接)。
答案 1 :(得分:0)
像这样使用
self.name = "Test"
ServiceProvider().saveVisitorEvent(visitor: self.visitor!, host:self.host!,isFromLocal:false) { [weak self] (success, errorMsg) in
self.name = ""
}