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