我以为我理解在复制的块中使用self是不能。
但是为了清理我的代码,我在Xcode中启用了一堆警告,一个叫做“向弱指针发送消息”
所以现在在我的所有块中,每次我使用我创建的weakself
引用__weak typeof(self) weakself = self;
我收到此警告:Weak receiver may be unpredictably set to nil
一个简单的例子:
__weak typeof(self) weakself = self;
[aClass doSomethingInABlock:^{
[weakself doSomething]; //warning.
}];
我已经看到了在块中定义自我版本的答案,如下所示:
__weak typeof(self) weakself = self;
[aClass doSomethingInABlock:^{
typeof(self) selfref = weakself;
[selfref doSomething]; //no warning.
}];
所以我想知道这里到底发生了什么:
感谢。
答案 0 :(得分:8)
我以为我理解在一个区块中使用self是不可能的。
这不是严格正确的。块将对象保留在其中,因此如果self
保留块,请不要在块中使用self
。
例如,您可以在UIView动画块中使用self
。这是因为您的视图控制器(或任何调用动画的代码)没有指向UIView动画块的指针。)
我只是在欺骗编译器吗?
没有
弱引用的强引用是什么?
如果弱引用不是nil
,则接收器的保留计数会增加。这将阻止对象在您使用时被释放。
请记住,当不再有强引用对象时,ARC将释放对象。通过在块内创建一个强引用,您可以防止可能的重新分配,直到您完成它。
我缺少的任何其他东西。
我建议您阅读高级内存管理编程指南的Practical Memory Management section。特别是,请阅读“使用弱引用以避免保留周期”小节。
答案 1 :(得分:3)
请记住,在ARC中,只要有一个强引用,对象就不会被释放。
当一个对象具有弱引用时,该对象可能会被释放(如果没有其他强引用同一个对象),那么弱引用不能确保对象的生命。
通过这样做:
typeof(self) selfref = weakself;
您确保在使用该对象之前对该对象有强引用(selfref
是指向同一对象的强引用weakself
是参考)。如果您不这样做,则在您使用 时可以取消分配该对象。
答案 2 :(得分:3)
对弱引用的强引用保留了一个对象。在以下案例中可能很重要
__weak typeof(self) weakself = self;
[aClass doSomethingInABlock:^{
[weakself allocateSomething]; // (1)
// ..... code (2)
[weakself freeSomething]; // (3)
}];
如果弱接收器在行(2)中被无法预测地设置为nil,则可以在(1)中成功分配资源但在(3)中不释放资源。为避免此类问题,可以使用强引用。
[aClass doSomethingInABlock:^{
typeof(self) selfref = weakself;
[selfref allocateSomething]; // (1)
// ..... code (2)
[selfref freeSomething]; // (3)
}];
现在,如果(1)中的selfref不为零,则它在(2)和(3)中也有效。