非优化与优化二进制中的奇怪ARC行为

时间:2013-01-16 10:33:11

标签: ios objective-c llvm

我有一个难以追踪的错误,它只出现在我的应用程序的Release版本中,但不出现在Debug版本中。构建之间的相关差异结果是Debug构建是在没有任何编译器优化的情况下编译的,而Release构建是使用-O编译的(该bug在所有其他优化设置上也是可重现的)。这完全在LLVM上。

在我的视图控制器中,我将属性self.basicInfoContainerView定义为:

@property (weak, nonatomic) IBOutlet UIView *basicInfoContainerView;

然后我从一个视图中删除了子视图,并将其添加到另一个视图中。

[self.basicInfoContainerView removeFromSuperview];
[self.infoTextView addSubview:self.basicInfoContainerView];

根据编译器优化级别,发生了不同的事情。

优化时:视图从超级视图中删除后,视图被取消分配,self.basicInfoContainerView为零,因此未作为子视图添加到新视图中。< / p>

关闭优化:子视图未立即取消分配,并成功添加为新视图的子视图。

(当我将属性存储限定符更改为strong时,视图在两种情况下都存活了,但即使这解决了问题,但这不是我的问题。)

我希望有人帮助我了解这里真正发生的事情。为什么weak在关闭编译器优化时不会立即释放我的视图(如果保留count == 0则将指针置零)?

1 个答案:

答案 0 :(得分:2)

看到非优化代码保留对对象的额外本地(和强)引用,这并不罕见。因此,未经优化的代码必须具有对此“basicInfoContainerView”的本地强引用。该引用通过该方法保留在范围内,并且可能在方法返回之前不会被释放。

这实际上只是掩盖了代码中真正错误的各种意外。事实上,只要你[self.basicInfoContainerView removeFromSuperview],你就不能指望你的basicInfoContainerView能够存活,因为你不再有任何明确的强引用。

当然,修复此问题的方法是创建对该视图的明确强引用。然后你已经向编译器明确了你的意图,你应该得到你想要的结果,无论代码是否优化:

UIView *containerView = self.basicInfoContainerView
// this local variable is that explicit strong reference you need

[containerView removeFromSuperview];
[self.infoTextView addSubview:containerView];

// the compiler can/will release this view when the local variable
// 'containerView' goes out of scope

希望有所帮助。