objective-c ios4 grand-central-dispatch nsnotifications

objective c - ¿Cómo publico una NSNotification cuando uso Grand Central Dispatch?



objective-c ios4 (2)

Descubrí que, como estaba previsto cuando estaba escribiendo una imagen en un archivo, mi UI estaba bloqueada durante todo el tiempo, lo que no era aceptable. Cuando escribo la imagen en el archivo, publico una Notificación NS para poder hacer otros trabajos específicos relacionados con esa finalización. Original de trabajo pero código de bloqueo de UI:

-(void)saveImageToFile { NSString *imagePath = [self photoFilePath]; BOOL jpgData = [UIImageJPEGRepresentation([[self captureManager] stillImage], 0.5) writeToFile:imagePath atomically:YES]; if (jpgData) { [[NSNotificationCenter defaultCenter] postNotificationName:kImageSavedSuccessfully object:self]; }

Para evitar el bloqueo de la interfaz de usuario, puse writeToFile: en una cola de Grand Central Dispatch para que se ejecute como un hilo concurrente. Pero cuando se completa la escritura y se termina el hilo, quiero publicar una NSNotificación. No puedo ya que el código se muestra aquí porque está en un hilo de fondo. Pero esa es la funcionalidad que quiero lograr, dándome cuenta de que esto no es un código viable:

-(void)saveImageToFile { NSString *imagePath = [self photoFilePath]; // execute save to disk as a background thread dispatch_queue_t myQueue = dispatch_queue_create("com.wilddogapps.myqueue", 0); dispatch_async(myQueue, ^{ BOOL jpgData = [UIImageJPEGRepresentation([[self captureManager] stillImage], 0.5) writeToFile:imagePath atomically:YES]; dispatch_async(dispatch_get_main_queue(), ^{ if (jpgData) { [[NSNotificationCenter defaultCenter] postNotificationName:kImageSavedSuccessfully object:self]; } }); }); }

¿Cuál es el mecanismo correcto aquí para publicar esta notificación para obtener la funcionalidad que quiero?


-(void)saveImageToFile { NSString *imagePath = [self photoFilePath]; // execute save to disk as a background thread dispatch_queue_t myQueue = dispatch_queue_create("com.wilddogapps.myqueue", 0); dispatch_async(myQueue, ^{ BOOL jpgData = [UIImageJPEGRepresentation([[self captureManager] stillImage], 0.5) writeToFile:imagePath atomically:YES]; dispatch_async(dispatch_get_main_queue(), ^{ if (jpgData) { [[NSNotificationCenter defaultCenter] postNotificationName:kImageSavedSuccessfully object:self]; } }); }); }

Eso ya es correcto. Sin embargo, ¿por qué necesita utilizar la notificación si ya ha enviado dispatch_get_main_queue ()?

Solo usa

dispatch_async(dispatch_get_main_queue(), ^{ if (jpgData) { //Do whatever you want with the image here } });

De todos modos su solución original está bien. No está bloqueando. Básicamente guardará el archivo en otro hilo y, una vez hecho, hará lo que sea necesario.

Lo que haga se hará en el mismo hilo con el hilo que llama a [[NSNotificationCenter defaultCenter] postNotificationName: kImageSavedSuccessfully object: self]; a saber, hilo principal.


Un par de posibilidades aquí.

1)

¿Qué tal [NSObject performSelectorOnMainThread: ...]?

P.EJ

-(void) doNotification: (id) thingToPassAlong { [[NSNotificationCenter defaultCenter] postNotificationName:kImageSavedSuccessfully object:thingToPassAlong]; } -(void)saveImageToFile { NSString *imagePath = [self photoFilePath]; // execute save to disk as a background thread dispatch_queue_t myQueue = dispatch_queue_create("com.wilddogapps.myqueue", 0); dispatch_async(myQueue, ^{ BOOL jpgData = [UIImageJPEGRepresentation([[self captureManager] stillImage], 0.5) writeToFile:imagePath atomically:YES]; dispatch_async(dispatch_get_main_queue(), ^{ if (jpgData) { [self performSelectorOnMainThread: @selector(doNotification:) withObject: self waitUntilDone: YES]; } }); }); }

Más detalles en http://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSObject_Class/Reference/Reference.html#//apple_ref/occ/instm/NSObject/performSelectorOnMainThread:withObject:waitUntilDone :

o 2)

Retrollamadas de finalización

como se ve en ¿Cómo puedo recibir una notificación cuando se completa una tarea dispatch_async?