Wo soll ich den Beobachter NSNotification
in Swift entfernen , da viewDidUnload
und dealloc()
nicht verfügbar sind?
Wo soll ich den Beobachter NSNotification
in Swift entfernen , da viewDidUnload
und dealloc()
nicht verfügbar sind?
Antworten:
Verwenden Sie die folgende Methode, die genauso funktioniert wie dealloc
.
deinit {
// Release all resources
// perform the deinitialization
}
Ein Deinitializer wird unmittelbar vor der Freigabe einer Klasseninstanz aufgerufen. Sie schreiben Deinitializer mit dem Schlüsselwort deinit, ähnlich wie Intializer mit dem Schlüsselwort init geschrieben werden. Deinitializer sind nur für Klassentypen verfügbar.
deinit
Methode für ViewControllerA wird nicht aufgerufen, wenn ViewControllerB gedrückt wird.
deinit
for ViewControllerA wird nur aufgerufen, wenn es sich nicht im Stapel des Navigationscontrollers befindet. Zum Beispiel: Wechseln zu rootViewController (wenn rootViewController nicht ViewControllerA ist)
deinit
. Idealer Ort zum Anrufen wärefunc viewDidDisappear(_ animated: Bool)
Ab iOS 9 (und OS X 10.11) müssen Sie Beobachter nicht mehr selbst entfernen , wenn Sie jedoch keine blockbasierten Beobachter verwenden. Das System erledigt dies für Sie, da es für Beobachter, wo dies möglich ist, auf Nullstellen schwache Referenzen verwendet.
Und wenn Sie blockbasierten Beobachter verwenden, stellen Sie sicher , dass Sie erfassen selbst schwach mit [weak self]
in der Schließung der Aufnahmeliste und entfernen Beobachter in deinit
Verfahren. Wenn Sie keinen schwachen Verweis auf sich selbst verwenden, wird die deinit
Methode (und damit das Entfernen dieses Beobachters) niemals aufgerufen, da das Notification Center auf unbestimmte Zeit einen starken Verweis darauf enthält.
Weitere Informationen finden Sie in den Foundation Release Notes für OS X 10.11 und iOS 9 .
Wenn der Beobachter als Referenz mit schwacher Nullung gespeichert werden kann, speichert der zugrunde liegende Speicher den Beobachter als Referenz mit schwacher Nullung. Alternativ kann das Objekt nicht schwach gespeichert werden (dh es verfügt über einen benutzerdefinierten Aufbewahrungs- / Freigabemechanismus, der die Laufzeit verhindert Wenn das Objekt nicht schwach gespeichert werden kann, wird es als nicht schwache Nullpunktreferenz gespeichert. Dies bedeutet, dass Beobachter sich bei ihrer Freigabemethode nicht abmelden müssen.
Blockbasierte Beobachter über die Methode - [NSNotificationCenter addObserverForName: object: queue: usingBlock] müssen noch abgemeldet werden, wenn sie nicht mehr verwendet werden, da das System immer noch einen starken Verweis auf diese Beobachter enthält.
delegate = nil
in dealloc()
Methode geschrieben. Funktioniert es ab jetzt genauso?
Sie können drei Methoden verwenden:
nach popViewController
, zurück navigationController
oder dismissViewControllerAnimated
:
deinit {
print("Remove NotificationCenter Deinit")
NSNotificationCenter.defaultCenter().removeObserver(self)
}
viewDidDisappear
, entfernen, nachdem es bereits der nächste View Controller ist:
override func viewDidDisappear(animated: Bool) {
NSNotificationCenter.defaultCenter().removeObserver(self)
}
viewWillDisappear
- bevor Sie die nächste Ansicht öffnen:
override func viewWillDisappear(animated: Bool) {
NSNotificationCenter.defaultCenter().removeObserver(self)
}
Schnelle 3.0-Syntax:
NotificationCenter.default.removeObserver(self)
In Swift 4.2 können Sie auf diese Weise Beobachter entfernen
deinit {
NotificationCenter.default.removeObserver(self, name: Notification.Name.Identifier, object: nil)
}
Richten Sie die addObserver-Benachrichtigung in der viewDidLoad-Klasse ein
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(didReceivedItemDetail), name: Notification.Name.Identifier, object: nil)
}
Swift bietet eine Deinit-Methode, die für Instanzen von Klassen aufgerufen wird, bevor sie zerstört werden.
Ich möchte auch darauf hinweisen, dass Sie diese Methode verwenden sollten:
func addObserver(_ observer: Any, selector aSelector: Selector, name aName: NSNotification.Name?, object anObject: Any?)
Anstatt
func addObserver(forName name: NSNotification.Name?, object obj: Any?, queue: OperationQueue?, using block: @escaping (Notification) -> Void) -> NSObjectProtocol
Letzterer wird den Beobachter nicht entfernen (ist kürzlich auf dieses Problem gestoßen). Ersteres entfernt den Beobachter, wenn Sie iOS9 verwenden.
dealloc
Methode nicht manuell entfernt haben .
deinit {
NotificationCenter.default.removeObserver(self)
}
Es ist auch gut, wenn Sie Ihren Beobachter hinzufügen viewWillAppear()
und entfernenviewWillDisappear()
Swift 5
Ich habe eine Chat-Anwendung. Wenn ich also von meinem ChatLogViewController zu einem anderen viewController wechsle und dann zurückkomme, habe ich 1 zusätzlichen Beobachter meiner Tastaturbenachrichtigung. Um dies zu entfernen, entferne ich alle Beobachter, wenn ich meinen viewController ändere oder aus meinem chatLogViewController verschwinde .
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
NotificationCenter.default.removeObserver(self)
}