8

我以为我理解 self 在复制的块中的用法是no no

但是为了清理我的代码,我在 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.

}];

我已经看到了在块中定义 self 版本的答案,如下所示:

__weak typeof(self) weakself = self;
[aClass doSomethingInABlock:^{
     typeof(self) selfref = weakself; 
     [selfref doSomething]; //no warning.

}];

所以我想知道这里实际发生了什么:

  • 我只是在欺骗编译器吗?
  • 强引用对弱引用有什么作用?
  • 我还缺少什么。

谢谢。

4

3 回答 3

8

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

这并不完全正确。块保留其中的对象,因此如果您self块由self.

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

我只是在欺骗编译器吗?

不。

强引用对弱引用有什么作用?

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

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

我还缺少什么。

我建议阅读 Advanced Memory Management Programming Guide 的Practical Memory Management 部分。特别是,请阅读“使用弱引用避免保留周期”小节。

于 2014-03-12T00:26:50.710 回答
3

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

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

通过做这个:

typeof(self) selfref = weakself; 

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

于 2014-03-12T00:25:05.290 回答
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)
}];

现在,如果 selfref 在 (1) 中不为零,它在 (2) 和 (3) 中也有效。

于 2014-03-12T00:30:54.357 回答