objective-c - notification - swift observer




Ziel C: Wo Beobachter für NSNotification entfernen? (10)

Ich habe eine objektive C-Klasse. Darin habe ich eine Init-Methode erstellt und darin eine NSNotification eingerichtet

//Set up NSNotification
[[NSNotificationCenter defaultCenter] addObserver:self 
                                         selector:@selector(getData)
                                             name:@"Answer Submitted"
                                           object:nil];

Wo setze ich das [[NSNotificationCenter defaultCenter] removeObserver:self] in dieser Klasse ein? Ich weiß, dass ich für einen UIViewController kann es in der viewDidUnload -Methode hinzufügen Also was muss getan werden, wenn ich gerade eine objektive c-Klasse erstellt?


Hinweis: Dies wurde getestet und funktioniert zu 100%

Schnell

override func viewWillDisappear(animated: Bool){
    super.viewWillDisappear(animated)

    if self.navigationController!.viewControllers.contains(self) == false  //any other hierarchy compare if it contains self or not
    {
        // the view has been removed from the navigation stack or hierarchy, back is probably the cause
        // this will be slow with a large stack however.

        NSNotificationCenter.defaultCenter().removeObserver(self)
    }
}

PräsentierterViewController

override func viewWillDisappear(animated: Bool){
    super.viewWillDisappear(animated)

    if self.isBeingDismissed()  //presented view controller
    {
        // remove observer here
        NSNotificationCenter.defaultCenter().removeObserver(self)
    }
}

Ziel c

In iOS 6.0 > version ist es besser, den Beobachter in viewWillDisappear zu entfernen, da viewDidUnload Methode viewDidUnload veraltet ist.

 [[NSNotificationCenter defaultCenter] removeObserver:observerObjectHere];

Es ist oft besser, remove observer zu remove observer wenn die Ansicht aus dem navigation stack or hierarchy .

- (void)viewWillDisappear:(BOOL)animated{
 if (![[self.navigationController viewControllers] containsObject: self]) //any other hierarchy compare if it contains self or not
    {
        // the view has been removed from the navigation stack or hierarchy, back is probably the cause
        // this will be slow with a large stack however.

        [[NSNotificationCenter defaultCenter] removeObserver:observerObjectHere];
    }
}

PräsentierterViewController

- (void)viewWillDisappear:(BOOL)animated{
    if ([self isBeingDismissed] == YES) ///presented view controller
    {
        // remove observer here
        [[NSNotificationCenter defaultCenter] removeObserver:observerObjectHere];
    }
}

* edit: Dieser Hinweis gilt für iOS <= 5 (auch dort sollten Sie in viewWillAppear hinzufügen und in viewWillAppear entfernen - der Ratschlag gilt jedoch, wenn Sie aus viewDidLoad Grund den Beobachter in viewDidLoad hinzugefügt viewDidLoad )

Wenn Sie den Beobachter in viewDidLoad hinzugefügt viewDidLoad , sollten Sie ihn sowohl in dealloc als auch in dealloc viewDidUnload . Andernfalls fügen Sie es am Ende zweimal hinzu, wenn viewDidLoad nach viewDidUnload (dies geschieht nach einer Speicherwarnung). Dies ist in iOS 6 nicht erforderlich, wenn viewDidUnload veraltet ist und nicht aufgerufen wird (weil die Ansichten nicht mehr automatisch entladen werden).


Die angenommene Antwort ist nicht sicher und könnte einen Speicherverlust verursachen. Bitte lassen Sie die Registrierung in dealloc aber auch abmelden in viewWillDisappear (das ist natürlich, wenn Sie sich in ViewWillAppear registrieren) .... Das ist, was ich schon immer getan habe und es funktioniert super! :)


Es ist wichtig zu beachten, dass viewWillDisappear auch viewWillDisappear wird, wenn der View-Controller eine neue UIView anzeigt. Dieser Delegat gibt lediglich an, dass die Hauptansicht des Ansichtscontrollers nicht auf dem Bildschirm angezeigt wird.

In diesem Fall ist es möglicherweise unangenehm, die Benachrichtigung in viewWillDisappear , wenn wir die Benachrichtigung verwenden, um der UIview die Kommunikation mit dem übergeordneten Ansichtscontroller zu ermöglichen.

Als Lösung entferne ich normalerweise den Beobachter in einer der beiden folgenden Methoden:

- (void)viewWillDisappear:(BOOL)animated {
    NSLog(@"viewController will disappear");
    if ([self isBeingDismissed]) {
        NSLog(@"viewController is being dismissed");
        [[NSNotificationCenter defaultCenter] removeObserver:self name:@"actionCompleted" object:nil];
    }
}

-(void)dealloc {
    NSLog(@"viewController is being deallocated");
    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"actionCompleted" object:nil];
}

Aus ähnlichen Gründen, wenn ich die Benachrichtigung zum ersten Mal ausstelle, muss ich berücksichtigen, dass jedes Mal, wenn eine Ansicht mit über dem Controller viewWillAppear wird, viewWillAppear Methode ausgelöst wird. Dies erzeugt wiederum mehrere Kopien derselben Benachrichtigung. Da es keine Möglichkeit gibt, zu überprüfen, ob eine Benachrichtigung bereits aktiv ist, beseitige ich das Problem, indem ich die Benachrichtigung vor dem Hinzufügen lösche:

- (void)viewWillAppear:(BOOL)animated {
    NSLog(@"viewController will appear");
    // Add observers
    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"imageGenerated" object:nil]; // This is added to avoid duplicate notifications when the view is presented again
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receivedImageFromCameraOrPhotolibraryMethodOnListener:) name:@"actionCompleted" object:nil];

}

Im Allgemeinen lege ich es in die dealloc Methode.


In schnellem Gebrauch deinit, da dealloc nicht verfügbar ist:

deinit {
    ...
}

Schnelle Dokumentation:

Ein Deinitializer wird unmittelbar vor dem Aufheben einer Klasseninstanz aufgerufen. Sie schreiben Deinitializer mit dem Schlüsselwort deinit, ähnlich wie Initializer mit dem Schlüsselwort init geschrieben werden. Deinitializer sind nur für Klassen verfügbar.

In der Regel müssen Sie die manuelle Bereinigung nicht durchführen, wenn die Zuordnung der Instanzen aufgehoben wird. Wenn Sie jedoch mit Ihren eigenen Ressourcen arbeiten, müssen Sie möglicherweise einige zusätzliche Bereinigungen selbst durchführen. Wenn Sie beispielsweise eine benutzerdefinierte Klasse erstellen, um eine Datei zu öffnen und Daten darauf zu schreiben, müssen Sie möglicherweise die Datei schließen, bevor die Klasseninstanz freigegeben wird.



Wenn der Beobachter einem View-Controller hinzugefügt wird , empfehle ich dringend, ihn in viewWillAppear hinzuzufügen und in viewWillAppear entfernen.


-(void) dealloc {
      [[NSNotificationCenter defaultCenter] removeObserver:self];
      [super dealloc];
}

override func viewDidLoad() {   //add observer
  super.viewDidLoad()
  NotificationCenter.default.addObserver(self, selector:#selector(Yourclassname.method), name: NSNotification.Name(rawValue: "NotificationIdentifier"), object: nil)
}

override func viewWillDisappear(_ animated: Bool) {    //remove observer
    super.viewWillDisappear(true)
    NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: "NotificationIdentifier"), object: nil)
}




nsnotifications