2016-02-10 5 views
1

Я использую NSXPCConnection и один из моих интерфейса вызова имеет ответ блок, как это:Как синхронно ждать ответа блока при использовании NSXPCConnection

- (void)addItem:(NSData *) withLabel:(NSString *) reply:(void (^)(NSInteger rc))reply; 

Что я называю так:

__block NSInteger status; 
[proxy addItem:data withLabel:@"label" reply:^(NSInteger rc) 
     { 
      status = rc; 
     } 
]; 

Я понимаю, что блок ответа выполняется асинхронно и потенциально после возвращения метода.

Я хочу проверить код возврата синхронно, что это лучший способ сделать это?


Для пояснения далее фрагмент сверху: proxy объекта является удаленным объектом, полученным из NSXPCConnection объекта с использованием методы remoteObjectProxy. Это важная деталь, так как это влияние на то, какая очередь вызывает ответный блок.

ответ

0

Я предлагаю использовать dispatch_semaphore.

// Create it before the block: 
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); 
__block NSInteger status = 0; 
[proxy addItem:data withLabel:@"label" reply:^(NSInteger rc) { 
      status = rc; 
      // In the block you signal the semaphore: 
      dispatch_semaphore_signal(semaphore); 
     } 
]; 

// here wait for signal 
// I dont remember exactly function prototype, but you should specify here semaphore and the time waiting (INFINITE) 
dispatch_semaphore_wait(...); 

// in non-ARC environment dont forget to release semaphore 
dispatch_release(semaphore); 

return status; 
+0

То, что я закончил делать (более или менее) – Droopycom

2

Я хочу проверить код возврата синхронно, что является лучшим способом для сделать это?

Вы действительно не хотите, чтобы он работал синхронно. Это просто заблокирует очередь/поток, над которым работает блок, и, как правило, приводит к сбою в работе.

Вместо этого, после строки status = rc;, позвоните, чтобы обработать тот факт, что это сделано. Пусть метод возвращается, пусть цикл очереди или события запускается, а затем выполняет работу, необходимую для выполнения addItem:withLabel:.


Как это:

__block NSInteger status; 
[proxy addItem:data withLabel:@"label" reply:^(NSInteger rc) { 
      status = rc; 
      // like this ... 
      [someObject processReturnedStatus]; 
     } 
]; 
+0

Метод, вызывающий этот код, должен возвращать код состояния, и у меня нет выбора: это интерфейс, который не под моим контролем. – Droopycom

3

Это то, что было сделано диспетчерские группы для.

NSTimeInterval timeout = 120; // in seconds 
__block NSInteger status; 

dispatch_group_t syncGroup = dispatch_group_create(); 
dispatch_group_enter(syncGroup); 

[proxy addItem:data withLabel:@"label" reply:^(NSInteger rc) 
    { 
     status = rc; 
     dispatch_group_leave(syncGroup); 
    } 
]; 

dispatch_time_t waitTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(NSEC_PER_SEC * timeout)); 

if(dispatch_group_wait(syncGroup, waitTime) != 0) 
{ 
    // complain about a request timing out 
} 

// enjoy your status 

, если вы решили использовать remoteObjectProxyWithErrorHandler, чтобы получить ваш прокси-сервер, то вам необходимо помнить также поместить вызов dispatch_group_leave (syncGroup) в обработчике ошибок.