简体   繁体   English

Swift 中的捕获列表

[英]Capture list in Swift

I have an example:我有一个例子:

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

if I change the closure like this:如果我像这样更改closure

var closure = { [weak a] in
    a = Animal()
    a?.stamina = 10
}

then it prints something like this:然后它会打印如下内容:

a.stamina // 0
a.increaseStamina()
a.stamina // 1
closure()
a.stamina // 1

Why is the last line different?为什么最后一行不同?

All entries in the capture list create a local variable in the closure.捕获列表中的所有条目在闭包中创建一个局部变量 It is initialized with the value of the variable with the same name in the outer context, but can be modified independently.它使用外部上下文中同名变量的值进行初始化,但可以独立修改。

In your case在你的情况下

var closure = { [weak a] in
    a = Animal()
    a?.stamina = 10
}

a inside the closure is initialized with a weak reference to the Animal object created before, but it is independent of the outer a variable. a封闭件内部初始化为弱参照Animal之前创建的对象,但它独立于外的a变量。 a = Animal() creates a new instance and assigns the reference to that local variable a . a = Animal()创建一个新实例并将引用分配给该局部变量a Because it is a weak reference, the object is deallocated immediately (you can verify that by adding print(a) in the closure).因为它是一个弱引用,所以该对象会立即被释放(您可以通过在闭包中添加print(a)来验证这一点)。 The outer variable a still references the original object:外部变量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

If you omit the capture list then a inside the closure and outside the closure refer to the same variable, and a new instance can be assigned inside the closure:如果省略了捕获列表,然后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

For more information and details, see "Capture Lists" in the Swift references (thanks so @Arthur for providing the link).有关更多信息和详细信息,请参阅 Swift 参考中的“捕获列表” (感谢 @Arthur 提供链接)。

Use like this, 像这样使用,

    self.name = "Test"
    ServiceProvider().saveVisitorEvent(visitor: self.visitor!, host:self.host!,isFromLocal:false) { [weak self] (success, errorMsg)  in
    self.name = ""
 }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM