Savoir quand un var faible devient nul dans Swift?

Disons que j'ai une weak var view: UIView? dans ma class Button {} . Est-il possible de savoir quand la view perd sa reference et devient nil ?

J'ai essayé d'utiliser la weak var view: UIView? {} weak var view: UIView? {} (alias une propriété calculée) pour surcharger set {} , mais cela n'a pas fonctionné parce que maintenant c'est une propriété calculée et ne peut pas stocker une reference faible (quelle ennuyeuse!).

Modifier:

La réponse de @fqdn n'a pas fonctionné avec ce code … Essayez-le dans un Xcode Playground

 import UIKit class Test { weak var target: UIView? { willSet { if !newValue { println("target set to nil") } else { println("target set to view") } } } } class Button { var view: UIView? = UIView() } var t = Test() var b = Button() t.target = b.view b.view = nil // t.target's willSet should be fired here 

Votre console de sortie devrait afficher:

 target set to view target set to nil 

Ma console affiche

 target set to view 

b.view est la reference forte pour l'instance UIView. t.target est la reference faible. Par conséquent, si b.view est défini sur nil , l'instance UIView est désallouée et t.target sera égale à nil.

Si votre button contient une reference à une autre vue, il devrait être soit un propriétaire de cette vue (c'est-à-dire, il devrait contenir une reference forte), soit il ne devrait pas se soucier quand cette vue disparaît (c.-à-d. .) Il n'y a pas de notification lorsque les references faibles deviennent nulles, et c'est par design.

En particulier, les observateurs de propriété Swift ne sont pas appelés lorsque les references faibles deviennent nulles, comme le montre le code suivant:

 class A : CustomSsortingngConvertible { var s: Ssortingng? init(s: Ssortingng) { self.s = s; print("\(self) init") } deinit { print("\(self) deinit") } var description: Ssortingng { get { return "[A s:\(s ?? "nil")]" } } } class B : CustomSsortingngConvertible { 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: Ssortingng { get { return "[B a:\(a == nil ? "nil" : Ssortingng(describing: a!))]" } } } func work() { var a: A? = A(s: "Hello") var b = B(a: a) print("\(b)") a = nil print("\(b)") ba = A(s: "Goodbye") } work() 

Lorsque work() est appelée, la console donne la sortie suivante:

 [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 

Remarquez que dans aucun cas de l'instance de A désallocation et de sa reference faible dans l'instance de B devenant nul, les observateurs de propriété sont appelés. Seulement dans le cas direct de l'assignation à Ba sont-ils appelés.