僵尸在后台线程中调用完成块时 [英] Zombie when calling completion block in background thread

查看:77
本文介绍了僵尸在后台线程中调用完成块时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将完成块传递给我的方法,当网络请求完成时,将在后台调用此完成块.不幸的是,如果同时释放调用对象,则应用程序将崩溃:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆