僵尸在后台线程中调用完成块时 [英] Zombie when calling completion block in background thread
问题描述
我将完成块传递给我的方法,当网络请求完成时,将在后台调用此完成块.不幸的是,如果同时释放调用对象,则应用程序将崩溃:
I pass a completion block to my method, this completion block will be called in the background when a network request is finished. Unfortunately, if the calling object is deallocated in the meantime, the app crashes:
ViewController(由于从导航堆栈中弹出,可能会被释放)代码:
ViewController (which may be deallocated because it's popped from the navigation stack) code:
__unsafe_unretained ViewController *weakSelf = self;
[[URLRequester instance] sendUrl:url successBlock:^(id JSON) {
[weakSelf webserviceCallReturned:JSON];
}];
URLRequester-Code(当然,要更简单):
URLRequester-Code (made simpler, of course):
- (void)sendUrl:(NSString *)urlAfterHost successBlock:(void (^)(id))successBlock {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
sleep(2);
successBlock(nil);
return;
});
}
如果在这2秒钟内ViewController从导航堆栈中弹出,则应用程序将崩溃.我想念什么?
If, in this 2 seconds, the ViewController gets popped from the navigation stack, the app crashes. What am I missing?
推荐答案
使用__unsafe_unretained
时,即使对象被释放后,引用仍然存在.因此,如果弹出视图控制器,则weakSelf
现在指向一个释放对象.
When you use __unsafe_unretained
, then the reference remains around even after the object is deallocated. So if the view controller gets popped, then weakSelf
is now pointing to a deallocated object.
如果将其更改为__weak
,则在取消分配视图控制器时,会将weakSelf
设置为nil
,就可以了.您甚至不需要检查weakSelf
是否设置为任何东西,因为在nil
上调用方法无效.
If you change it to __weak
instead, then when the view controller gets deallocated, it will set weakSelf
to nil
, and you'll be fine. You don't even need to do a check for if weakSelf
is set to anything, because calling a method on nil
has no effect.
这篇关于僵尸在后台线程中调用完成块时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!