Extending the example from the other thread a little:
class Ref {
weak var obj: Obj? {
didSet { print(obj == nil ? "is nil" : "is not nil") }
}
}
class Obj {
weak var ref: Ref?
func unlink(from ref: Ref) {
print(ref.obj as Any)
}
deinit {
print("deinit")
ref.map(unlink(from:))
}
}
var obj: Obj? = Obj()
let ref = Ref()
obj?.ref = ref
ref.obj = obj
obj = nil
The result is:
is not nil
deinit
nil
Why don't we track and fire the didSet observable when the object becomes nil? If there is a technical reason, so be it. However if not then it seems logical to me that the output should look like this:
is not nil
is nil
deinit
nil
jrose
(Jordan Rose)
2
If that were the case, that would mean releasing any class could have arbitrary side effects beyond what's in the deinit, because anyone could have made a weak variable referencing it. That's something we try to avoid in Swift.
Beyond that, pure Swift weak properties don't even get set to nil immediately; they do it the next time you load from the property. (This is different from Objective-C weak references.) So there's also not even a place to put a call to the setter today.
8 Likes