我编写了一个示例代码来建立服务器连接。请找到我在下面写的代码。
__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:
方法。
能否请您帮我解决此问题。
提前致谢。
答案 0 :(得分:2)
答案是抓住强有力的参考。除非self
具有对完成块的引用,否则您无论如何都不会有保留周期。无论如何,当块返回时,强引用将被释放,如果碰巧有一个就会打破周期。
答案 1 :(得分:1)
我真的很想知道,为什么人们认为每次捕获它都需要削弱自我。
正如术语保留周期所说,如果你引用一个引用第一个引用的对象的对象(直接或通过其他一些引用),你只能有一个
因此,如果块上下文引用self
,则当前和仅当self
引用块时,您有一个引用周期。 (顺便说一句:这适用于每一个(强)参考。在Objective-C中没有任何关于self
的任何特殊内容。)你没有。 在您的情况下,防止保留周期没有理由弱化self
。
然而,有些人希望弱化它,在这种情况下制作self
nil
。这是意图。在某些情况下,这可能是一个优势:只需考虑在为其下载数据时已经消失的模型对象。没有理由让它保持活力。
如果您不想这样,只需不要弱化self
。 那么简单。
答案 2 :(得分:0)
这个想法是下载数据不应该让你的对象保持活力。如果您的对象在下载运行时消失(例如,如果用户从屏幕切换导致下载到另一个屏幕),那么您应该忽略结果并将其丢弃,或者将其存储到文件中,但是您应该让自己变成零。
这与参考周期无关:如果你不使用weakSelf,self 将最终消失,但是你不应该让它保持比所需更长的时间。最糟糕的情况是,您可能会向用户显示一条错误警告,该警告已经消失了。失败的URL请求可能需要60秒才能失败,因此用户可能已经做了一些完全不同的事情。
使用weakSelf的正确方法是将其分配给回调中的新变量strongSelf,然后检查它是否为nil。直接使用weakSelf是不好的,因为它可以随时变为零。