ARC,自我和块

时间:2014-03-12 00:20:41

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

我以为我理解在复制的块中使用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.

}];

所以我想知道这里到底发生了什么:

  • 我只是在欺骗编译器吗?
  • 弱引用的强引用是什么?
  • 我缺少的任何其他内容。

感谢。

3 个答案:

答案 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)中也有效。