3

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

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

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

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

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

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

优化:一旦视图从其父视图中删除,视图就会被释放并self.basicInfoContainerView归零,因此不会作为子视图添加到新视图中。

关闭优化:子视图没有立即解除分配,而是作为子视图成功添加到新视图中。

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

我希望有人能帮助我了解这里到底发生了什么。weak当编译器优化关闭时,为什么不立即释放我的视图(如果保留计数 == 0,则将指针归零)?

4

1 回答 1

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

希望有帮助。

于 2013-01-16T23:41:26.703 回答