Gdzie powinienem usunąć obserwatora NSNotification
w Swift, skoro viewDidUnload
i dealloc()
są niedostępne?
ios
swift
nsnotifications
Clement Joseph
źródło
źródło
Odpowiedzi:
Użyj poniższej metody, która działa tak samo jak
dealloc
.deinit { // Release all resources // perform the deinitialization }
Swift Deinitializer
źródło
deinit
Metoda @Kampai dla ViewControllerA nie zostanie wywołana, gdy będzie push ViewControllerB.deinit
for ViewControllerA zostanie wywołane tylko wtedy, gdy nie ma go na stosie kontrolera nawigacji. Na przykład: Przełączanie na rootViewController (jeśli rootViewController nie jest ViewControllerA)deinit
. Idealne miejsce by zadzwonićfunc viewDidDisappear(_ animated: Bool)
Od iOS 9 (i OS X 10.11) nie musisz usuwać obserwatorów , jeśli jednak nie używasz obserwatorów blokowych. System zrobi to za Ciebie, ponieważ używa słabych zerowo referencji dla obserwatorów, gdzie tylko może.
A jeśli używasz obserwatorów opartych na blokach, upewnij się, że uchwyciłeś siebie słabo za pomocą
[weak self]
listy przechwytywania zamknięcia i usuń obserwatora wdeinit
metodzie. Jeśli nie użyjesz słabego odniesienia do siebie,deinit
metoda (a tym samym usunięcie tego obserwatora) nigdy nie zostanie wywołana, ponieważ Centrum powiadomień będzie utrzymywać silne odniesienie do niego przez czas nieokreślony.Więcej informacji można znaleźć w informacjach o wydaniu Foundation dla systemu OS X 10.11 i iOS 9 .
źródło
delegate = nil
wdealloc()
metodzie. Czy od teraz działa tak samo?Możesz użyć trzech metod:
po
popViewController
, z powrotemnavigationController
lubdismissViewControllerAnimated
:deinit { print("Remove NotificationCenter Deinit") NSNotificationCenter.defaultCenter().removeObserver(self) }
viewDidDisappear
, usuń, gdy jest już następnym kontrolerem widoku:override func viewDidDisappear(animated: Bool) { NSNotificationCenter.defaultCenter().removeObserver(self) }
viewWillDisappear
- przed otwarciem kolejnego widoku:override func viewWillDisappear(animated: Bool) { NSNotificationCenter.defaultCenter().removeObserver(self) }
Składnia Swift 3.0:
NotificationCenter.default.removeObserver(self)
źródło
W Swift 4.2 jest to jeden ze sposobów usuwania obserwatora
deinit { NotificationCenter.default.removeObserver(self, name: Notification.Name.Identifier, object: nil) }
skonfigurować powiadomienie addObserver w klasie viewDidLoad
override func viewDidLoad() { super.viewDidLoad() NotificationCenter.default.addObserver(self, selector: #selector(didReceivedItemDetail), name: Notification.Name.Identifier, object: nil) }
źródło
Swift zapewnia metodę deinit, która jest wywoływana na wystąpieniach klas, zanim zostaną zniszczone.
https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Deinitialization.html
źródło
Chcę również zaznaczyć, że powinieneś użyć tej metody:
func addObserver(_ observer: Any, selector aSelector: Selector, name aName: NSNotification.Name?, object anObject: Any?)
Zamiast
func addObserver(forName name: NSNotification.Name?, object obj: Any?, queue: OperationQueue?, using block: @escaping (Notification) -> Void) -> NSObjectProtocol
Ten ostatni nie usunie obserwatora (ostatnio napotkałem ten problem). Pierwsza z nich usunie obserwatora, jeśli używasz iOS9.
źródło
dealloc
metodzie.deinit { NotificationCenter.default.removeObserver(self) }
źródło
Szybki 5
Mam aplikację do czatu, więc za każdym razem, gdy przechodzę z mojego ChatLogViewController do innego ViewController, a następnie wracam, mam 1 dodatkowego obserwatora mojego powiadomienia z klawiatury. Aby to usunąć, usuwam wszystkich obserwatorów, gdy zmieniam viewController lub znikam z mojego chatLogViewController .
override func viewDidDisappear(_ animated: Bool) { super.viewDidDisappear(animated) NotificationCenter.default.removeObserver(self) }
źródło
Dobrze jest również dodać obserwatorów
viewWillAppear()
i usunąć ichviewWillDisappear()
źródło