web-dev-qa-db-fra.com

Où supprimer l'observateur de NSNotification dans Swift?

Où devrais-je retirer l'observateur de NSNotification dans Swift, puisque viewDidUnload et dealloc() ne sont pas disponibles?

68
Clement Joseph

Utilisez la méthode ci-dessous qui fonctionne de la même manière que dealloc.

deinit {
    // Release all resources
    // perform the deinitialization
}

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.

désinitialiseur rapide

62
Kampai

À partir de iOS 9 (et de OS X 10.11), vous n'avez pas besoin de supprimer les observateurs vous-même, si vous n’utilisez pas d’observateurs basés sur des blocs. Le système le fera pour vous, car il utilise les références faibles pour les observateurs, dans la mesure du possible.

Et si vous utilisez des observateurs basés sur des blocs, assurez-vous de vous capturer faiblement en utilisant [weak self] dans la liste de capture de la fermeture, et supprime l'observateur dans la méthode deinit. Si vous n'utilisez pas de référence faible à self, la méthode deinit (et donc le retrait de cet observateur) ne sera jamais appelée, car le Centre de notification gardera une référence forte à cette référence indéfiniment.

Pour plus d'informations, consultez la page Notes de version de Foundation pour OS X v10.11 et iOS 9 .

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.

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.

105
Nikola Milicevic

Vous pouvez utiliser trois méthodes:

1 - après popViewController, retour navigationController ou dismissViewControllerAnimated:

deinit {
        print("Remove NotificationCenter Deinit")
        NSNotificationCenter.defaultCenter().removeObserver(self)
    }

ou

2 - viewDidDisappear, supprimez-le s'il est déjà le prochain contrôleur de vue:

override func viewDidDisappear(animated: Bool) {
        NSNotificationCenter.defaultCenter().removeObserver(self)
    }

ou

3 - viewWillDisappear - avant d’ouvrir la vue suivante:

override func viewWillDisappear(animated: Bool) {
    NSNotificationCenter.defaultCenter().removeObserver(self)
}

syntaxe Swift 3.0:

NotificationCenter.default.removeObserver(self)
49
Pablo Ruan

Dans Swift 4.2, C’est l’un des moyens de supprimer l’observateur

deinit {
    NotificationCenter.default.removeObserver(self, name: Notification.Name.Identifier, object: nil)
}

configurer la notification addObserver dans la classe viewDidLoad

override func viewDidLoad() {
    super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(didReceivedItemDetail), name: Notification.Name.Identifier, object: nil)
}
9
Ashim Dahal

Swift fournit une méthode deinit qui est appelée sur les instances de classes avant leur destruction.

https://developer.Apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Deinitialization.html

3
pmick

Je tiens également à souligner que vous devriez utiliser cette méthode:

func addObserver(_ observer: Any, selector aSelector: Selector, name aName: NSNotification.Name?, object anObject: Any?)

Au lieu de

func addObserver(forName name: NSNotification.Name?, object obj: Any?, queue: OperationQueue?, using block: @escaping (Notification) -> Void) -> NSObjectProtocol

Ce dernier n’éliminera pas l’observateur (récemment exploré ce problème). Le premier va supprimer l'observateur si vous utilisez iOS9.

2
Guy Daher

C'est également bien si vous ajoutez votre observateur dans viewWillAppear() et le supprimez dans viewWillDisappear()

0
mayank khare