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