ARC (Automatic Reference Counting) — système de gestion automatique de la mémoire en Swift. Chaque nouvelle référence forte à un objet augmente le compteur ; lors de la suppression, il diminue. Lorsque le compteur est à zéro, l'objet est libéré.
Cycle de rétention — situation où des objets se réfèrent mutuellement par des références fortes et ne sont jamais libérés.
Moyens d'éviter :
protocol SomeDelegate: AnyObject { } class Owner { weak var delegate: SomeDelegate? }
[weak self] ou [unowned self] :class Example { var closure: (() -> Void)? func setup() { closure = { [weak self] in self?.doSomething() } } func doSomething() { } }
Quelle est la différence entre [weak self] et [unowned self] à l'intérieur d'une closure ? Quel type de référence utiliser et quand ?
Réponse :
[weak self] crée une référence optionnelle ; self peut être nil, donc on utilise généralement une extraction sécurisée self?.[unowned self] crée une référence non-optionnelle et n'augmente PAS le compteur ; si l'objet est déjà libéré et qu'un accès se produit — cela provoquera un crash.[unowned self].Exemple :
someClosure = { [weak self] in self?.doTask() } // ou (si self vit 100% plus longtemps que la closure) : someClosure = { [unowned self] in doTask() }
Histoire
Dans un projet, une situation de cycle de rétention s'est formée entre ViewController et sa closure, attachée à la gestion des pressions. ViewController se référencait à la closure, qui capturait self par une référence forte. En conséquence, le contrôleur et toutes ses données n'étaient pas libérés après la fermeture de l'écran. Le problème a été résolu en introduisant [weak self] dans la closure.
Histoire
Mise en œuvre du modèle delegate entre deux objets. Le delegate a été déclaré comme une propriété forte (
strong). En conséquence, lors de la tentative de suppression de l'objet principal de la mémoire, il n'était pas désalloué, ce qui a conduit à une fuite de mémoire. Après avoir transféré le delegate sur weak, le problème a disparu.
Histoire
Pour une animation, une closure était utilisée à l'intérieur de UIView. La closure capturait self avec
[unowned self]. Lorsque la vue était supprimée avant la fin de l'animation, l'application plantait en raison d'un accès à self déjà libéré. La solution — utilisation de[weak self]et vérification obligatoire que self n'est pas nil à l'intérieur de la closure.