8

Estoy tratando de obtener el ID de una etiqueta, usando una biblioteca.haga algo de trabajo en segundo plano y devuelva el resultado

Se me ocurrió lo siguiente. el bucle que busca una etiqueta se hace en segundo plano y obtengo un resultado correcto en tagAsString.

-(void) readTag { 
    NSLog(@"readTag"); 
    unsigned char * tagUID = (unsigned char *) malloc(M1K_UID_SIZE * sizeof(char)); 
    //work to do in the background 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
     ERR ret; 
     while ((ret = scanner->IsTagAvailable(tagUID)) != ERR_TAG_AVAILABLE) { 
      NSLog(@"ret: %d", ret); 
     } 


     //main thread 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      if(ret == ERR_TAG_AVAILABLE) { 
       NSLog(@"tag available"); 
       NSString *tagAsString = [[[NSString alloc] initWithFormat:@"%x%x%x%x", tagUID[0],tagUID[1],tagUID[2],tagUID[3]] retain]; 

      } 
     }); 
    }); 
} 

Me gustaría ser capaz de devolver ese valor, así que sería capaz de llamar a:

NSString * myTag = [self readTag]; 

es posible? Gracias por su ayuda, Michael

Respuesta

12

Es posible, sin embargo, el problema de devolver una cadena de esa función es que tendría que mantener su hilo de llamada mientras realiza el trabajo en segundo plano, perdiendo así el beneficio de el hilo de fondo. (dispatch_sync es lo que usarías para hacer eso, sin embargo, no lo recomendaría).

Al usar bloques, es mejor reestructurar su programa para que se ajuste mejor con el paradigma asincrónico. Cuando el trabajo está completo debe notificar lo que está esperando en el resultado enviándole un mensaje con el resultado. En su ejemplo, pondría esto en el bloque de código que distribuye en la cola principal.

@interface TagManager 
- (void)fetchTag; 
- (void)tagFetched:(NSString *)tag; 
@end 

@implementation TagManager 
- (void)fetchTag { 
    // The following method does all its work in the background 
    [someObj readTagWithObserver:self]; 
    // return now and at some point someObj will call tagFetched to let us know the work is complete 
} 

- (void)tagFetched:(NSString *)tag { 
    // The tag read has finished and we can now continue 
} 
@end 

Luego, su función readTag se modificaría de manera:

- (void)readTagWithObserver:(id)observer { 
    ... 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
     ... 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      if (tag is ok) { 
       [observer tagFetched:tag]; 
      } 
     }); 
    });       
} 

La idea principal es que tiene que dividir su procesamiento en dos etapas

  1. solicitando que parte del trabajo es hecho (fetchTag en mi ejemplo)
  2. procesa el resultado cuando termina (tagFetched: en mi ejemplo)
+0

Gracias por su respuesta. ¿Quiere decir usar NSNotification para notificar o hay alguna otra manera? – Themikebe

+0

NSNotification es una manera posible, sin embargo, en este ejemplo solo usaría message passing (llamadas a métodos). Editaré mi respuesta con un ejemplo – jjwchoy

Cuestiones relacionadas