8

Bir kitaplık kullanarak kimliği bir etiketten almaya çalışıyorum.arka planda bazı işler yapın ve sonucu döndürün

Aşağıdakilerle geldim. Bir etiket için görünen döngü arka planda yapılır ve tagAsString'de doğru bir sonuç alırım.

Aramam mümkün olacaktır böylece değer döndürmek edebilmek istiyorum

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

      } 
     }); 
    }); 
} 
:

NSString * myTag = [self readTag]; 

mümkün olabilir? Yardımlarınız için teşekkürler, Michael

cevap

12

Bu işlevden bir dizgenin döndürülmesi ile ilgili sorun, arka planda çalışmayı yaparken çağrı iş parçacığınızı tutmak zorunda kalmasıdır - böylece arka plan iş parçacığı. (dispatch_sync bunu yapmak için kullanacağınız şeydir - ancak bunu tavsiye etmem).

Blokları kullanırken, programınızı asenkron paradigma ile daha iyi uyum sağlayacak biçimde yeniden yapılandırmak en iyisidir. Çalışma tamamlandığında, sonuçta ona bir mesaj yollayarak, sonuçta ne bekliyorsa onu bilgilendirmelidir. Örneğinizde bunu ana sıraya göndereceğiniz kod bloğuna koyarsınız.

@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 

Sonra readTag fonksiyonu böylece şekilde değişecektir:

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

ana fikri bazı eseridir isteyen iki aşamada

  1. içine işleme bölmek gerektiğidir tamamlandı (örneğimde fetchTag)
  2. işlemi tamamlandığında sonucu işleyin (tagFetched: örneğimde)
+0

Cevabınız için teşekkür ederiz. Bildirmek için NSNotification kullanmak mı yoksa başka yolu var mı? – Themikebe

+0

NSNotification olası bir yoldur, ancak bu örnekte sadece mesaj geçişini kullanacağım (yöntem çağrıları). Cevabımı bir örnekle düzenleyeceğim – jjwchoy

İlgili konular