这个问题是类似于this question与自动参考计数投入。从的NSOperation子类(ARC)使用块回调主线程
我有一个NSOperation
子类,接受旨在作为回调一个块参数到主(UI)线程。我的初衷是在后台执行一些操作,然后使用dispatch_async
和主队列执行回调。
原始前提:当被删除到块的范围之外的UIKit的对象的所有引用出现
@interface MySubclass : NSOperation {
@protected
dispatch_block_t _callback;
}
- (id)initWithCallback:(dispatch_block_t)callback;
@end
@implementation MySubclass
- (void)main
{
// Do stuff
if (![self isCancelled]) {
dispatch_async(dispatch_get_main_queue(), _callback);
}
}
@end
问题。 (例如,从导航堆栈弹出UIViewController
)。这留下了块内对象的唯一引用,因此当块被解除分配的线程上时,对象被解除分配。重新分配一个对象的UIKit关闭主线程崩溃,并显示错误消息Tried to obtain the web lock from a thread other than the main thread or the web thread. This may be a result of calling to UIKit from a secondary thread. Crashing now...
变通方法是应用程序,我加了__block
修正回调伊娃,和现在用dispatch_sync
使释放确保一切都在主线程上。
@interface MySubclass : NSOperation {
@protected
__block dispatch_block_t _callback;
}
- (id)initWithCallback:(dispatch_block_t)callback;
@end
@implementation MySubclass
- (void)main
{
// Do Stuff
if (![self isCancelled]) {
dispatch_block_t block = ^{
_callback();
_callback = nil;
};
// Cover all our bases to prevent deadlock
if ([NSThread isMainThread]) block();
else dispatch_sync(dispatch_get_main_queue(), block);
}
}
@end
我想知道是否有更好的方法来完成这个前提。我的解决方法让人感觉很不舒服,而且我不喜欢这样,我可能会在我的队列中完成几项操作,并在完成之前等待主线程启动。
另一方面,我遇到了在代码结束时检查的类型的死锁,所以现在使用主线程上的dispatch_sync助手函数:http://stackoverflow.com/questions/5225130/grand-central-dispatch-gcd-vs-performselector-need-a-better-explanation/5226271#5226271 –