Objective-C 大师,
我一直在使用以下宏来确保 block 在主线程上运行。这个想法很简单:如果我当前在主线程上,那么我将立即运行该 block 。如果当前线程不是主线程,那么我会将要在主线程上异步运行的 block 排队(这样它就不会阻塞当前线程)。
你认为这有什么问题吗?这里有什么不安全的东西,或者导致我不知道的错误吗?有更好的方法吗?
#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;
}
最佳答案
这可能会导致执行顺序出现严重的细微错误。
拿这个简单的例子(在主线程上)
__block NSInteger integer = 5;
run_on_main(^{
integer += 10;
});
NSLog(@"From Main %d", integer);
这将打印结果 15
相同的代码在后台线程中运行
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
__block NSInteger integer = 5;
run_on_main(^{
integer += 10;
});
NSLog(@"From background %d", integer);
});
结果将是 5
... 或 15
,具体取决于线程之间的竞争条件。
这种不一致可能会误导您。
为什么不在这两种情况下都使用 dispatch_async
并且安全地知道两者现在将表现出相同的行为。这是安全和好的,因为您使用的是非阻塞的 async
关于ios - 这个 run_on_main() 宏有什么问题吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15529860/