Objective-C大師,這個run_on_main()宏有什麼問題嗎?
我一直在使用下面的宏來確保塊在主線程上運行。這個想法很簡單:如果我目前在主線程上,那麼我會立即運行該塊。如果當前線程不是主線程,那麼我將該塊排列爲在主線程上異步運行(以便它不會阻塞當前線程)。
您是否發現此問題?這裏有什麼不安全的地方,或者導致我不知道的錯誤?有沒有更好的方法來做到這一點?
#define run_on_main(blk) if ([NSThread isMainThread]) { blk(); } else { dispatch_async(dispatch_get_main_queue(), blk); }
實例應用:
-(BOOL)loginCompletedSuccessfully
{
NSLog(@"loginCompletedSuccessfully");
// This may be called from a network thread, so let's
// ensure the rest of this is running on the main thread.
run_on_main(^{
if (_appStartupType == AppLaunch) {
self.storyboard = [UIStoryboard storyboardWithName:DEVICED(@"XPCStoryboard") bundle:nil];
self.navigationController = [storyboard instantiateInitialViewController];
}
[self.window setRootViewController:self.navigationController];
});
return YES;
}
爲什麼不使用'dispatch_async'來覆蓋這兩種情況?看起來很奇怪,在一種情況下,塊立即執行,另一種情況下很快就會在某一時刻運行 - 您的代碼無法確定它將在哪個線程上運行,而無需檢查它們首先處於哪個線程,從而破壞了這一點?所以我想我試圖說執行順序是不同的,這取決於你在哪個線程,但調用代碼不知道這 – 2013-03-20 17:00:22
@ Paul.s - 原因很簡單:如果我在MainThread上,那麼我關心關於執行順序。如果我不在主線程中,那麼我只是想將塊放到下一個可用位置的主線程中,而不會無意中造成死鎖狀態。當一個方法由於UI事件或者後臺線程的網絡響應而不知道它是否被調用時,這很重要。 – 2013-03-20 19:12:34
如果您使用'dispatch_sync',但您的示例使用'dispatch_async',這是一種非阻塞方法 – 2013-03-20 19:14:43