Sea*_*ser 7 cocoa objective-c foundation nsthread ios
我遇到了这个_cmd伎俩:
-(void)methodToBeRunOnMainThreadWithObj:(id)object {
if (![NSThread isMainThread) {
[self performSelectorOnMainThread:_cmd withObject:object]
} else {
// ... method body
}
}
Run Code Online (Sandbox Code Playgroud)
这是确保在主线程上执行方法的可靠方法吗?
这有效,但有点反模式.如果调用方法的线程不是主线程,我会做的是抛出错误.调用者有责任确保在正确的线程上调用方法,这些类型的黑客只会鼓励丑陋的代码.此外,如果您依赖于此,突然您每次调用此方法时都会将消息调度开销加倍.
如果您真的无法更改调用方的行为,可以尝试以下操作:
-(void)methodToBeRunOnMainThreadWithObj:(id)object {
dispatch_sync(dispatch_get_main_queue(), ^{
// code goes here
});
}
Run Code Online (Sandbox Code Playgroud)
这将导致调度块中的所有代码在主线程上执行,并且该方法在完成之前不会返回.如果您希望该方法立即返回,则可以dispatch_async改为使用.如果使用dispatch_sync,即使对于具有非void返回类型的方法,也可以使用此技巧.
此代码还具有支持具有非对象类型(int等)的参数的方法的额外好处.它还支持具有任意数量参数的方法,而performSelector:withObject:其兄弟方法仅支持有限数量的参数.另一种方法是设置NSInvocation对象,这些都很痛苦.
请注意,这需要您平台上的Grand Central Dispatch(GCD).