Ich bin noch neu zu Blöcken in objective-c und frage mich, ob ich diesen Pseudo-Code richtig habe. Ich bin mir nicht sicher, ob es genug ist, um nur den Beobachter zu entfernen oder wenn ich removeObserver müssen nennen: Name: Objekt:Korrekte Verwaltung von addObserverForName: Objekt: Warteschlange: usingBlock:
-(void) scan {
Scanner *scanner = [[Scanner alloc] init];
id scanComplete = [[NSNotificationCenter defaultCenter] addObserverForName:@"ScanComplete"
object:scanner
queue:nil
usingBlock:^(NSNotification *notification){
/*
do something
*/
[[NSNotificationCenter defaultCenter] removeObserver:scanComplete];
[scanner release];
}];
[scanner startScan];
}
Update: Ich intermittierende EXC_BAD_ACCESS
von diesem Block bin empfangen, so kann dies nicht sein Recht.
Sie brauchen '__block id scanComplete;', oder es wird in den Block kopiert und Sie werden Beobachter leckt. – hwaxxer
In der Welt von ARC gilt der Kommentar zur Verwendung von '__block' zur Vermeidung von Capture nicht mehr. Was _does_ stimmt, ist, dass der '__block' Qualifikationsmerkmal ein fundamentales Problem behebt: wenn der Block definiert ist,' addObserverForName: ...'ist noch nicht zurückgekehrt, daher ist der Wert, der erfasst wird, bestenfalls 'nil' (wenn er unter ARC wegen seiner impliziten automatischen Nullpunkt-Variablendeklaration ausgeführt wird) oder ** undefined ** und tauscht einen BAD_ACCESS für völlig undefiniertes Verhalten , im schlimmsten Fall ... – danyowdee
Das Entfernen des Beobachters durch Bezugnahme auf eine lokale Variable innerhalb des Blocks war immer skanky. Speichern Sie das zurückgegebene Beobachter-Token (hier "scanComplete") als Instanzvariable; Unter ARC sollte dies eine '__weak'-Instanzvariable sein, um einen Retain-Zyklus auf self zu verhindern. – matt