2012-10-11 65 views
3

我想弄清楚什麼特殊的屬性NSRunLoop有導致以下行爲。dispatch_group_wait不能按預期運行,除非與NSRunLoop一起使用?

首先,我想要做的是等待CLGeocoder在繼續前完成執行。如果我用的是完成塊,代碼將是這個樣子:

if (/* loc has valid coordinates */) 
    [gc reverseGeocodeLocation:loc completionHandler:^(NSArray *placemarks, NSError error){ 
     //do things 
     [gc reverseGeocodeLocation:newloc completionHandler:^(NSArray *placemarks, NSError error){ 
      //do more things with newloc 
      // MOVE TO NEXT VIEW 
     } 
    } 
else if (/*still have to check for newloc*/) 
    [gc reverseGeocodeLocation:loc completionHandler:^(NSArray *placemarks, NSError error){ 
     //do things 
     //MOVE TO NEXT VIEW 

不幸的是這些區塊的//do things部分是冗長的,它會是乾淨得多,如果我在自己的函數嵌套CLGeocoder,並轉移到下一個視圖曾經被稱爲兩次。

我找到了一種方法來強制等待感謝答案在這裏:Waiting for CLGeocoder to finish on concurrent enumeration

因此,新方法的工作,但我不知道爲什麼它的工作原理。下面的代碼:

dispatch_group_t group = dispatch_group_create(); 
dispatch_group_enter(group); 

[gc reverseGeocodeLocation:loc completionHandler:^(NSArray *placemarks, NSError *error){ 
    //do things 
    dispatch_group_leave(group); 
} 

//this is the confusing part! 
while(dispatch_group_wait(group,DISPATCH_TIME_NOW)){ 
    [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode 
          beforeDate:[NSDate dateWithTimeIntervalSinceNow:1.0f]]; 
} 
dispatch_release(group); 

奇怪的是,如果我做不while循環下,應用程序掛起:

dispatch_group_wait(group,DISPATCH_TIME_FOREVER); 

放棄一切我到目前爲止閱讀,應該工作,對不對?


更令人困惑的是,NSRunLoop在while循環中是必需的。如果我完全刪除它,留下一個空的while循環,循環將無止境地重複。像這樣:

//this is the confusing part! 
while(dispatch_group_wait(group,DISPATCH_TIME_NOW)){ 
    //without NSRunLoop, this just goes on forever 
} 

什麼NSRunLoop這樣做可以讓while循環爲順利結束?

回答

2

CLGeocoder文檔說它運行主線程上的完成處理程序塊。我推斷你在主線程上運行永久等待或你的while(dispatch_group_wait(...))循環。如果阻塞主線程,主線程將無法運行完成塊。

通過在while循環中調用runMode:beforeDate:,您可以爲運行循環提供運行完成塊的機會。

你在做什麼是不好的。你不應該阻塞主線程,你應該儘量避免運行一個運行循環(因爲你已經發現它是令人困惑的)。 CLGeocoder可以讓你提供一個完成塊的原因是,你可以設置它,然後返回到主運行循環。稍後,當CLGeocoder運行完成塊時,可以以任何您需要的方式使用結果。

+0

我同意我在做什麼是壞的,但CLGeocoder對我們沒有用,除非它返回。我想我會回到嵌套的geocoder-in-completion-block,因爲以這種方式強制同步似乎很危險。 – ray

相關問題