8

J'essaie d'obtenir l'ID d'une étiquette, en utilisant une bibliothèque.faire un travail en arrière-plan et retourner le résultat

J'ai trouvé ce qui suit. la boucle qui cherche un tag est faite en arrière-plan et j'obtiens un résultat correct dans 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]; 

      } 
     }); 
    }); 
} 

Je voudrais être en mesure de retourner cette valeur si je serais en mesure d'appeler:

NSString * myTag = [self readTag]; 

est-ce possible? Merci pour votre aide, Michael

Répondre

12

Il est possible, cependant, le problème avec le retour d'une chaîne de cette fonction est qu'il devrait tenir votre thread appelant pendant que vous effectuez le travail en arrière-plan - perdant ainsi le bénéfice de le fil d'arrière-plan. (dispatch_sync est ce que vous utiliseriez pour le faire - mais je ne le recommanderais pas). Lors de l'utilisation de blocs, il est préférable de restructurer votre programme pour mieux l'adapter au paradigme asynchrone. Lorsque le travail est terminé, il doit notifier ce qui est en attente sur le résultat en lui envoyant un message avec le résultat. Dans votre exemple, vous mettez ceci dans le bloc de code que vous distribuez dans la file d'attente principale.

@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 

Ensuite, votre fonction ReadTag serait modifié comme si:

- (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]; 
      } 
     }); 
    });       
} 

L'idée principale est que vous devez diviser votre traitement en deux étapes

  1. demande que certains travaux sont done (fetchTag dans mon exemple)
  2. traiter le résultat quand il se termine (tagFetch: dans mon exemple)
+0

Merci pour votre réponse. Voulez-vous dire utiliser une NSNotification pour notifier ou existe-t-il un autre moyen? – Themikebe

+0

NSNotification est une façon possible, mais dans cet exemple, j'utiliserais simplement le passage de message (appels de méthode). Je vais éditer ma réponse avec un exemple – jjwchoy

Questions connexes