estoy todavía nuevo en bloques en Objective-C y se preguntan si tengo esta pseudo código correcto. No estoy seguro de si es suficiente para eliminar sólo el observador o si tengo que llamar removeObserver: Nombre: Objeto:gestión correcta de addObserverForName: Objeto: cola: 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];
}
Actualización: Estoy recibiendo intermitente EXC_BAD_ACCESS
de este bloque, por lo que no puedo estar derecho.
Necesita '__block id scanComplete;', o se copiará en el bloque y tendrá filtraciones de observadores. – hwaxxer
En el mundo de ARC, el comentario sobre el uso de '__block' para evitar la captura ya no es válido. Lo que _desea_ es cierto, es que el calificador '__block' soluciona un problema fundamental: cuando se define el bloque,' addObserverForName: ...'aún no ha regresado, por lo que el valor que se captura es' nil' en el mejor de los casos (cuando se ejecuta en ARC, debido a su declaración de variable auto-nil implícita), o ** indefinido **, intercambiando un BAD_ACCESS por un comportamiento completamente indefinido , en el peor de los casos ... – danyowdee
Quitar al observador haciendo referencia a una variable local desde el interior del bloque siempre fue superficial. Almacene el token de observador devuelto (aquí, 'scanComplete') como una variable de instancia; en ARC esto debería ser una variable de instancia '__weak' para evitar un ciclo de retención en sí mismo. – matt