ARC,自我和块

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

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

  • 我只是欺骗编译器?
  • 强引用弱引用有什么作用?
  • 我缺少的任何其他东西。

谢谢。

我以为我理解在一个块中使用self是不可能的。

这不是严格正确的。 块保留其中的对象,因此如果块被self保留 ,则不要在块中使用self

例如,您可以在UIView动画块中使用self 。 这是因为您的视图控制器(或任何调用动画的代码)没有指向UIView动画块的指针。)

我只是欺骗编译器?

没有。

弱引用的强引用是做什么的?

如果弱参考不是nil ,则接收器的保持计数增加。 这将阻止对象在您使用时被释放。

请记住,当不再有强引用对象时,ARC将释放对象。 通过在块内创建一个强引用,您可以防止可能的重新分配,直到您完成它。

我缺少的任何其他东西。

我建议阅读“高级内存管理编程指南”中的“ 实际内存管理”部分 。 特别是,请阅读“使用弱引用以避免保留周期”小节。

请记住,在ARC中,只要有强烈的引用,对象就不会被释放。

当一个对象具有弱引用时,该对象可能被释放(如果没有对同一对象的其他强引用),则弱引用不能确保对象生命。

通过做这个:

 typeof(self) selfref = weakself; 

在使用它之前,你要确保你对该对象有一个引用( selfref是指向weakself指的同一个对象的强引用)。 如果不这样做,则可以在使用对象时释放该对象。

对弱引用的强引用保留了一个对象。 在以下情况下这可能很重要

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