我知道之前已经问过这个问题,但是没有解决方案可以解决我的问题,所以我再次问这个问题。我试图通过块回调来调用self上的方法。我收到以下错误:
在此区块中强烈捕捉'自我'可能会导致保留周期
- (void)viewDidLoad {
[super viewDidLoad];
self.webClient.completionHandler = ^{
[self populateData];
};
}
我尝试过类似下面的代码,我仍然得到同样的警告。 解决方案是什么?
__weak id myself = self;
[myself populateData];
答案 0 :(得分:4)
您的代码应如下所示:
- (void)viewDidLoad {
[super viewDidLoad];
__weak id weakSelf = self;
self.webClient.completionHandler = ^{
[weakSelf populateData];
};
}
答案 1 :(得分:0)
UIAdam给出了正确的答案,但值得理解为什么它是正确的。
首先,你为什么得到警告?
self对webClient有强烈的引用。 webClient强烈引用completionHandler。 completionHandler强烈提到自我。因此,如果程序中的所有其他引用都消失了,那么在此循环中仍然会强烈引用每个项目,因此它们永远不会被释放。
写作的尝试
__weak id myself = self;
[myself populateData];
当然没有工作。该块仍然引用self,因为它将它分配给我自己。所以这里没有区别。
UIAdam的写作解决方案
__弱id weakSelf = self; self.webClient.completionHandler = ^ { [weakSelf populateData]; };
表示weakSelf是弱引用,并且该块仅包含对self的弱引用。因此,如果所有其他强烈的自我引用都消失了,那么只剩下一个弱引用。弱引用并不能保持自我活动,因此自我被释放。
现在如果发生这种情况会怎么样,但是其他东西对webClient有强烈的引用并且你的块被调用了? weakSelf是一个弱引用,当对象被释放时,弱引用被设置为nil。因此,当你的块被调用时,你必须准备好weakSelf为nil。写
实际上更好id strongSelf = weakSelf;
[strongSelf populatedData];
块内的:strongSelf可能设置为nil,或者它将设置为self。但由于它是一个强大的参考,它将保持非零,直到块完成。如果开始时不是零。