在 iOS 7.1 更新中自动释放的变量崩溃,但在 iOS 7.1 之前的操作系统版本中工作正常

Posted

技术标签:

【中文标题】在 iOS 7.1 更新中自动释放的变量崩溃,但在 iOS 7.1 之前的操作系统版本中工作正常【英文标题】:Autoreleased variable crashes in iOS 7.1 update, but working fine in OS versions prior to iOS 7.1 【发布时间】:2014-05-30 06:39:08 【问题描述】:

我遇到了一个奇怪的问题。我有一段代码如下:

UIView *myView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, 280, 380)] autorelease];
// then I add some view componetns to this view...
[self.view addSubView:myView];
[myView release];

根据我的理解,一旦在 myView 变量上调用释放消息,或者一旦线程上发生自动释放池耗尽,这段代码就会崩溃。

但是,这段代码在 ios 7.1 之前的 iOS 版本中运行良好(我在 iOS 6.0、7.0、7.0.4 中测试过)。但它在 iOS 7.1 和 7.1.1 更新中崩溃。

谁能告诉我发生内存释放崩溃的确切原因。任何为什么它不会在早期版本中崩溃。

【问题讨论】:

你最好在你的项目中使用 ARC @robmayoff 你确定吗?他自动释放,然后手动释放。 我无法向右滚动。 ;^)。这就是我删除评论的原因。 它在早期版本中不会崩溃,因为过度发布是未定义的行为,未定义的行为不需要是可预测的。但是,如果您在启用僵尸的情况下运行,您可能也会在早期 iOS 版本中检测到错误。 @robmayoff 不一定。如果系统出于任何原因过度保留对象,则可能无法立即检测到。 【参考方案1】:

您错误地释放了myView。要么让自动释放池在耗尽时释放myView,要么通过调用release 手动释放它。现在,您在方法结束时释放它一次,然后自动释放耗尽再次错误地释放它,导致对象被释放。然后系统尝试访问视图并崩溃。

addSubviews: 增加保留计数,然后您立即释放它。然后autorelease通过allocation/init释放init retain。

至于为什么它不会崩溃,这并不重要。可能是系统过度保留了视图,因此该对象在 7.1 中不再存在,但仍处于活动状态。但这并不重要,问题出在您的代码中。

【讨论】:

等等,addSubview: 不增加保留计数器? 没有 ARC 就没有保留计数器,是吗? @gaussblurinc 是的,但是这与答案无关。 @jrturton,不明白为什么 OP 代码不正确。两个保留,两个释放。只是因为视图生活中的某个地方myView 被释放并且iOS 7.1 尝试访问它? @gaussblurinc addSubviews: 增加保留计数,然后您立即释放它。然后autorelease通过allocation/init释放init retain。【参考方案2】:

您在为对象分配内存时已经使用了自动释放,并且在添加视图后再次释放它。您可以删除 autorelease 或删除 [myView release]。

【讨论】:

以上是关于在 iOS 7.1 更新中自动释放的变量崩溃,但在 iOS 7.1 之前的操作系统版本中工作正常的主要内容,如果未能解决你的问题,请参考以下文章

在 removeFromParent 上 Sprite Kit iOS 7.1 崩溃

XCode 6项目在ios 7.1上segue后崩溃

在自动释放 ios 项目中保留变量

iOS 7.1 removeFromSuperview 崩溃

KeychainWrapperItem 在 iOS 7.1 中停止工作

Xcode 6 Beta 在 iPad 7.1 上运行时使用核心数据使应用程序崩溃