Je souhaite effectuer un nettoyage à la fin de la vie d'un contrôleur de vue, notamment pour supprimer une notification NSNotificationCenter
. L'implémentation de dealloc
entraîne une erreur de compilateur Swift:
Cannot override 'dealloc' which has been marked unavailable
Quel est le moyen préféré d'effectuer un nettoyage à la fin de la vie d'un objet dans Swift?
deinit {
// perform the deinitialization
}
De la Swift Documentation :
Un désinitialiseur est appelé immédiatement avant qu'une instance de classe ne soit désallouée. Vous écrivez desinitialiseurs avec le mot clé deinit, similaire à la façon dont les initiaux sont écrits avec le mot clé init. Les déinitialiseurs ne sont disponibles que sur les types de classe.
En règle générale, vous n'avez pas besoin d'effectuer un nettoyage manuel lorsque vos instances sont désallouées. Toutefois, lorsque vous utilisez vos propres ressources, vous devrez peut-être effectuer un nettoyage supplémentaire vous-même. Par exemple, si vous créez une classe personnalisée pour ouvrir un fichier et y écrire des données, vous devrez peut-être fermer le fichier avant que l'instance de la classe ne soit désallouée.
deinit {
// perform the deinitialization
}
est la bonne réponse pour Swift "dealloc".
Cependant, il est bon de signaler que, dans iOS 9, il n’est plus nécessaire de nettoyer NSNotificationCenter!
NSNotificationCenter
Sous OS X 10.11 et iOS 9.0, NSNotificationCenter et NSDistributedNotificationCenter n'enverront plus de notifications aux observateurs enregistrés susceptibles d'être désalloués. Si l’observateur peut être stocké en tant que référence de mise à zéro faible, le stockage sous-jacent le stockera en tant que référence de mise à zéro faible, ou si l’objet ne peut pas être stocké de manière faible (c’est-à-dire qu’il dispose d’un mécanisme de conservation/libération personnalisé qui empêcherait le temps d’exécution. de pouvoir stocker l’objet faiblement) il stockera l’objet en tant que référence de réduction à zéro non faible. Cela signifie que les observateurs ne sont pas tenus de se désinscrire de leur méthode de désallocation. La prochaine notification qui serait acheminée vers cet observateur détectera la référence mise à zéro et annulera automatiquement l'inscription de l'observateur. Si un objet peut être faiblement référencé, les notifications ne seront plus envoyées à l'observateur lors de la désallocation; le comportement précédent de réception des notifications pendant dealloc est toujours présent dans le cas des observateurs de référence dont la mise à zéro est faible. Les observateurs basés sur des blocs via la méthode - [NSNotificationCenter addObserverForName: object: queue: usingBlock] doivent toujours être désenregistrés lorsqu'ils ne sont plus utilisés, car le système conserve toujours une référence forte à ces observateurs. La suppression prématurée des observateurs (référencés faiblement ou mis à zéro) est toujours prise en charge. CFNotificationCenterAddObserver ne se conforme pas à ce comportement car l'observateur peut ne pas être un objet.
mais notez les points ci-dessous concernant les références fortes, de sorte que vous devrez peut-être vous soucier du nettoyage de toute façon ...
Swift libère automatiquement vos instances lorsqu'elles ne sont plus nécessaires pour libérer des ressources. Swift gère la gestion de la mémoire des instances par le biais du comptage automatique des références (ARC), comme décrit dans la section Comptage automatique des références. En règle générale, vous n'avez pas besoin d'effectuer un nettoyage manuel lorsque vos instances sont désallouées. Toutefois, lorsque vous utilisez vos propres ressources, vous devrez peut-être effectuer un nettoyage supplémentaire vous-même. Par exemple, si vous créez une classe personnalisée pour ouvrir un fichier et y écrire des données, vous devrez peut-être fermer le fichier avant que l'instance de la classe ne soit désallouée.
Les définitions de classe peuvent avoir au plus un désinitialiseur par classe. Le désinitialiseur ne prend aucun paramètre et est écrit sans parenthèses:
deinit { // perform the deinitialization }
il est nécessaire de retirer l'observateur avant la désallocation, sinon un crash se produirait. Cela peut être fait en utilisant
deinit {
// perform the deinitialization
print("deinit")
removeObserver(self, forKeyPath: kSelectedViewControllerKey, context: nil)
removeObserver(self, forKeyPath: kSelectedIndexKey, context: nil)
}