我有一个难以追踪的错误,它只出现在我的应用程序的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则将指针置零)?
答案 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
希望有所帮助。