Ответ 1
Если ваша кнопка удерживает ссылку на другое представление, она должна быть либо владельцем этого представления (т.е. содержать сильную ссылку), либо не должно заботиться о том, когда этот вид уходит (т.е. его слабая ссылка на он становится нулем.) Нет уведомлений, когда слабые ссылки становятся нулевыми, и это по дизайну.
В частности, наблюдатели свойств Swift не вызывают, когда слабые ссылки становятся равными нулю, как показывает следующий код:
class A : CustomStringConvertible {
var s: String?
init(s: String) {
self.s = s;
print("\(self) init")
}
deinit {
print("\(self) deinit")
}
var description: String {
get { return "[A s:\(s ?? "nil")]" }
}
}
class B : CustomStringConvertible {
weak var a:A? {
willSet {
print("\(self) willSet a")
}
didSet {
print("\(self) didSet a")
}
}
init(a: A?) {
self.a = a
print("\(self) init")
}
deinit {
print("\(self) deinit")
}
var description: String {
get { return "[B a:\(a == nil ? "nil" : String(describing: a!))]" }
}
}
func work() {
var a: A? = A(s: "Hello")
var b = B(a: a)
print("\(b)")
a = nil
print("\(b)")
b.a = A(s: "Goodbye")
}
work()
Когда вызывается work()
, консоль дает следующий вывод:
[A s:Hello] init
[B a:[A s:Hello]] init
[B a:[A s:Hello]]
[A s:Hello] deinit
[B a:nil]
[A s:Goodbye] init
[B a:nil] willSet a
[B a:[A s:Goodbye]] didSet a
[A s:Goodbye] deinit
[B a:nil] deinit
Обратите внимание, что ни в случае, когда экземпляр A deallocating, а его слабая ссылка в случае B, становящегося nil, являются вызывающими свойствами наблюдателями. Только в прямом случае присвоения B.a они называются.