2013-06-10 4 views
5

Ich habe nächsten Code:removeObserver nicht funktioniert

@implementation SplashViewVC 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    self.splashView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"Default.png"]]; 
    self.activityIndicator.originY = 355.f; 
    [[NSNotificationCenter defaultCenter] addObserverForName:NCDownloadComplete object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *n){ 
     NSInteger errorCode = [n.userInfo[@"errorCode"] integerValue];   
     [self.activityIndicator stopAnimating]; 
     if (errorCode == ERROR_CODE_NO_CONNECTION) { 
      UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Some problem with server" delegate:self cancelButtonTitle:@"try again" otherButtonTitles:nil]; 
      [alertView show]; 
     } else if (errorCode == 0) { 
      [self dismissViewControllerAnimated:YES completion:nil]; 
     } 
    }]; 
    [self downloadData]; 
} 

- (void)downloadData 
{ 
    [self.activityIndicator startAnimating]; 
    [[Server sharedServer] getMovieData]; 
} 

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex 
{ 
    [self downloadData]; 
} 

- (void)viewDidDisappear:(BOOL)animated 
{ 
    [[NSNotificationCenter defaultCenter] removeObserver:self]; 
    [super viewDidDisappear:animated]; 
} 

@end 

Also habe ich Haltepunkte in der viewDidLoad Methode beginnen, in viewDidDisappear. Wenn ich eine App starte, die zuerst zu viewDidload geht, gehe ich nach dem Download zu viewDidDisappear.

Aber während meiner App ich wieder Daten herunterladen und notification: NSDownloadComplete. Und in diesem VC ist es Arbeit, aber ich entfernte später mit:

[[NSNotificationCenter defaultCenter] removeObserver:self] 

Diese VC-Nutzung viewDidLoad einmal am Anfang & kann nicht wieder addObserver.

Was ist los?

EDIT Ich versuche setzen addObserver Methode viewWillAppear oder viewWillDisappear - ohne Ergebnisse. ich hinzufügen NSLog(@"addObserver"); vor

[[NSNotificationCenter defaultCenter] addObserverForName... 

in viewDidLoad

und schreiben

- (void)viewDidDisappear:(BOOL)animated 
{ 
    NSLog(@"removeObserver"); 
    [[NSNotificationCenter defaultCenter] removeObserver:self]; 
    [super viewDidDisappear:animated]; 
} 

In log ich sehe:

2013-06-10 14:32:05.646 myApp[9390:c07] addObserver 
2013-06-10 14:32:06.780 myApp[9390:c07] removeObserver 

was falsch?

EDIT 2 Sie, dass Beobachter entfernt werden sehen müssen, aber es wieder Block in addObserver Verfahren laufen

enter image description here

+3

Ist das Code copy & geklebt? Ich frage mich nur, weil Ihre 'viewDidLoad' nur 3 Zeilen lang ist und danach gibt es Anweisungen, die in keiner Methode enthalten sind. Das ist nicht valide;) – HAS

+0

@HAS alle funktionieren gut, bis auf meine Frage =) – user2213271

+0

Sorry, aber das ist nicht;) Die geschweifte Klammer nach 'self.activityIndicator.originY = 355.f;' ist falsch. Entfernen Sie und Sie werden gültigen Code haben;) – HAS

Antwort

24

Neben hinzufügen/entfernen Beobachter ruft nicht richtig ist ausgeglichen, um in den anderen Antworten erwähnt, gibt es ein weiteres Problem.

Ihr Code zum Entfernen des Beobachters ist falsch. Für einen blockbasierten Beobachter muss der Rückgabewert von addObserver als Argument removeObserver angegeben werden. Sie sollten also eine Klasse hinzufügen

@property(nonatomic, strong) id observer; 

in die Klasse. Dann fügen Sie den Betrachter mit

self.observer = [[NSNotificationCenter defaultCenter] addObserverForName:NCDownloadComplete object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *n){ 
    // ... 
}]; 

und entfernen Sie sie mit

[[NSNotificationCenter defaultCenter] removeObserver:self.observer]; 
+0

Ja, das löst mein Problem Danke =) – user2213271

+0

danke dir so Martin, deine lösung funktioniert so gut. – Wilson

3

Das Muster, das Sie verwenden, sind nicht korrekt. Sie sollten den Beobachter in viewDidAppear: hinzufügen und in viewDidDisappear: entfernen.

+1

oder fügen Sie den Beobachter in 'viewWillAppear:' –

+1

@ e1985 nicht helfen. Und viewWillAppear: helfe auch nicht – user2213271

5

Was e1985 auszusetzen versucht, ist, dass Ihre addObserver und removeObserver Anrufe nicht richtig ausbalanciert sind. viewDidLoad wird nur einmal nach der VC-Initialisierung aufgerufen, aber viewDidDisappear wird jedes Mal aufgerufen, wenn der Ansichtscontroller vom Bildschirm entfernt wird.

Ihr Problem zu beheben, müssen Sie Ihre addObserver und removeObserver Anrufe entweder ausgleichen, indem sie in viewDidLoad und die andere in dealloc machen, oder - wie e1985 vorgeschlagen - in viewDidAppear: und viewDidDisappear:.

EDIT: Ok, also Ihr Problem kommt von der Tatsache, dass Sie addObserverForName:object:queue:usingBlock: verwenden, die nicht self als Beobachter registrieren (wie addObserver:selector:name:object: tun würde, wenn Sie self als erstes Argument übergeben).

Also in Ihrem Fall, [[NSNotificationCenter defaultCenter] removeObserver:self]; tut nichts, weil self kein Beobachter ist.Sie sollten stattdessen removeObserver: auf dem Rückgabewert von addObserverForName:object:queue:usingBlock: nennen, wie in the doc gezeigt:

Rückgabewert

ein undurchsichtiges Objekt als Beobachter zu fungieren.

So Ihr Code sollte wie folgt aussieht:

// header file .h 
@interface SplashViewVC : UIViewController 

@property (strong, nonatomic) id downloadCompleteObserver; 

@end 

// implementation file .m 
@implementation SplashViewVC 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    // [...] snip 

    self.downloadCompleteObserver = [[NSNotificationCenter defaultCenter] addObserverForName:NCDownloadComplete object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *n){ 
     NSInteger errorCode = [n.userInfo[@"errorCode"] integerValue];   
     [self.activityIndicator stopAnimating]; 
     if (errorCode == ERROR_CODE_NO_CONNECTION) { 
      UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Some problem with server" delegate:self cancelButtonTitle:@"try again" otherButtonTitles:nil]; 
      [alertView show]; 
     } else if (errorCode == 0) { 
      [self dismissViewControllerAnimated:YES completion:nil]; 
     } 
    }]; 
    [self downloadData]; 
} 

// [...] snip 

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

@end 
+0

Ich bewege mich in viewDidAppear: und keine Ergebnisse = ( – user2213271

+0

Bitte erklären Sie das Problem dann klarer. Was ist "nicht funktioniert"? –

+0

ich Bildschirm hinzufügen, wo Sie diesen Block nach removeObserver Methode aufgerufen werden können. – user2213271

Verwandte Themen