弱自我在块内部变为nil但我想在块内使用self对象

时间:2016-07-22 05:19:48

标签: ios objective-c automatic-ref-counting objective-c-blocks

我编写了一个示例代码来建立服务器连接。请找到我在下面写的代码。

__weak typeof(self) weakSelf = self;
self.dataTask = [defaultSession dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)
{
    weakSelf.dataTask = nil;
    NSInteger extractionResponseCode = [((NSHTTPURLResponse *)response) statusCode];
    if (!error && data.length > 0 && extractionResponseCode == 200)
    {
        [weakSelf handleResponse:data];
    }
    else
    {
        [weakSelf handleError:error];
    }
}];

收到回复后,我必须根据回复拨打handleResponse:handleError:

我已经将weakSelf用于避免ARC中的保留周期问题。

我的问题是在块内弱自己变为零,因此不会调用handleResponse:handleError:方法。

能否请您帮我解决此问题。

提前致谢。

3 个答案:

答案 0 :(得分:2)

答案是抓住强有力的参考。除非self具有对完成块的引用,否则您无论如何都不会有保留周期。无论如何,当块返回时,强引用将被释放,如果碰巧有一个就​​会打破周期。

答案 1 :(得分:1)

我真的很想知道,为什么人们认为每次捕获它都需要削弱自我。

正如术语保留周期所说,如果你引用一个引用第一个引用的对象的对象(直接或通过其他一些引用),你只能有一个

因此,如果块上下文引用self,则当前和仅当self引用块时,您有一个引用周期。 (顺便说一句:这适用于每一个(强)参考。在Objective-C中没有任何关于self的任何特殊内容。)你没有。 在您的情况下,防止保留周期没有理由弱化self

然而,有些人希望弱化它,在这种情况下制作self nil。这是意图。在某些情况下,这可能是一个优势:只需考虑在为其下载数据时已经消失的模型对象。没有理由让它保持活力。

如果您不想这样,只需不要弱化self 那么简单。

答案 2 :(得分:0)

这个想法是下载数据不应该让你的对象保持活力。如果您的对象在下载运行时消失(例如,如果用户从屏幕切换导致下载到另一个屏幕),那么您应该忽略结果并将其丢弃,或者将其存储到文件中,但是您应该让自己变成零。

这与参考周期无关:如果你不使用weakSelf,self 最终消失,但是你不应该让它保持比所需更长的时间。最糟糕的情况是,您可能会向用户显示一条错误警告,该警告已经消失了。失败的URL请求可能需要60秒才能失败,因此用户可能已经做了一些完全不同的事情。

使用weakSelf的正确方法是将其分配给回调中的新变量strongSelf,然后检查它是否为nil。直接使用weakSelf是不好的,因为它可以随时变为零。