我有一个关于在特定示例中的闭包中如何处理对对象的引用的问题。下面的代码被简化以展示这个想法
class SomeObject {
init(value: Int) {
self.value = value
}
var value: Int {
didSet {
valueObservers.forEach { $0(value) }
}
}
var valueObservers = [(Int) -> Void]()
}
class TestClass {
let obj1 = SomeObject(value: 1)
let obj2 = SomeObject(value: 2)
let obj3 = SomeObject(value: 3)
func valueOfObjectChanged(object: SomeObject) {
print("Value of object \(object) is \(object.value)")
}
init() {
let objects = [obj1, obj2, obj3]
objects.forEach { (object) in
object.valueObservers.append { [unowned self] (_) in
self.valueOfObjectChanged(object: object)
}
}
}
}
所以我们这里有一个类SomeObject
,它可以存储一个闭包数组,当其变量的值发生变化时将执行这些闭包。TestClass
创建一些这样的对象,然后从这些对象中创建数组,并为这个数组中的每个对象添加一个闭包,该闭包将执行一个函数,TestClass
当任何这些对象的值SomeObjects
发生变化时。
好的,现在在这个可以由任何创建的对象触发的函数中,我想确定我知道哪个对象实际上导致它执行。引用在函数执行中传递,但请注意,object
这里是从循环中获取并传递给闭包(闭包将执行 valueOfObjectChanged 并将对象引用作为参数传递)。
那有什么问题 - 我不确定对对象的引用是否真的会保留给正确的对象,因为这个闭包在与创建闭包时完全不同的地方执行。
我不能把object
这个关闭capture list
,因为这会导致Segmentation fault: 11
。
我不确定在这种情况下闭包会如何表现 - 会保留对对象的引用,还是会出错?
我也可以在定义中添加调用者valueObservers
,但由于应用程序的当前结构,这是我想避免的(示例只是一个简化)。
所以我的问题是 - 对object
under的引用是否object.valueObservers.append
总是正确的,并且指向改变了它的值的对象,或者它是否不正确,例如指向最后一个被迭代的对象,objects.forEach
甚至是其他东西?