Wciąż jestem nowy dla bloków w celu-c i zastanawiam się, czy mam ten kod psuedo poprawny. Nie jestem pewien, czy to wystarczy po prostu usunąć obserwatora czy mam zadzwonić removeObserver: Nazwa: obiekt:Poprawne zarządzanie addObserverForName: object: queue: 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: Otrzymuję przerywany EXC_BAD_ACCESS
z tego bloku, więc to nie może być dobrze.
Potrzebujesz '__block id scanComplete;', lub zostanie on skopiowany do bloku i będziesz przeciekać obserwatorów. – hwaxxer
W świecie ARC komentarz dotyczący używania '__block' w celu uniknięcia przechwytywania nie jest już prawdziwy. To, co _ jest prawdą, jest takie, że kwalifikator '__block' naprawia podstawowy problem: po zdefiniowaniu bloku' addObserverForName: ...'jeszcze się nie zwróciło, więc przechwycona wartość jest w najlepszym razie' nil' (gdy działa pod ARC, z powodu niejawnego automatycznego braku w deklaracji zmiennej) lub ** niezdefiniowana **, wymienia jedną BAD_ACCESS na całkowicie niezdefiniowane zachowanie , w najgorszym wypadku ... – danyowdee
Usunięcie obserwatora przez odwołanie się do zmiennej lokalnej z wnętrza bloku było zawsze kłujące. Przechowuj zwrócony token obserwatora (tutaj, 'scanComplete') jako zmienną instancji; pod ARC powinna to być zmienna instancji '__weak', aby zapobiec cyklowi zatrzymania na sobie. – matt