在Swift中捕获列表

时间:2016-09-13 08:43:50

标签: ios swift

我有一个例子:

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

为什么最后一行不同?

2 个答案:

答案 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 = ""
 }