【问题标题】:Obj-C message sent to deallocated object (EXEC_BAD_ACCESS), with iOS5, ARCObj-C 消息发送到已释放对象 (EXC_BAD_ACCESS),使用 iOS5、ARC
【发布时间】:2012-01-21 03:00:00
【问题描述】:

我正在使用 ARC 开发 iOS5 应用程序,我开始遇到一些我无法弄清楚的随机 EXEC_BAD_ACCESS 崩溃。随机是指它非常不可预测:有时可能需要很长时间才能崩溃,有时可能很短.而且也没有一个特定的按钮/表格单元/等。触发崩溃。每次用户交互都可能使应用程序崩溃,但您不能重复崩溃。

我尝试打开 NSZombie 以及一些 malloc 调试器工具。在 Instruments 中,崩溃错误为:Objective-C 消息已发送到地址为 0x10bd1b40 的已释放对象(僵尸)。引用计数日志的最后一部分是这样的:

475 CoursesFirstViewController  Release 2   02:23.253.631   0   UIKit   -[UINibDecoder finishDecoding]
476 CoursesFirstViewController  Release 1   02:23.253.838   0   Foundation  -[NSAutoreleasePool drain]
477 CoursesFirstViewController  Zombie  -1  02:35.752.420   0   Foundation  objectHash

2、1、-1 是引用计数。我不知道为什么它会跳过 0 并下降到 -1,从而使程序崩溃(除最后一个之外的所有条目都有连续的引用计数)。我也不知道 objectHash 是什么。

我的应用程序包含多个功能,可作为主屏幕上的图标访问。 CoursesFirstViewController 是功能之一。总是,CoursesFirstViewController 和 objectHash 使应用程序崩溃,即使我在其他地方也是如此。 (上面的日志就是这种情况:我在 02:23 离开 CoursesFirstViewController(从而返回到我的应用程序的主屏幕),但 12 秒后,当我在其他一些功能中时,应用程序崩溃了)我只需要进入CourseFirstViewController,弄乱一会,然后去别的地方继续使用,过一会就崩溃了。

我现在真的对这个问题很生气。我已经搜索了 SO 和 Google 很长一段时间,但找不到解决方案。任何帮助将不胜感激。谢谢!!

【问题讨论】:

  • 您是否设法获得了几次出现的堆栈跟踪,或者它是您唯一拥有的?
  • @zneak 抱歉,什么是堆栈跟踪?是 NSLog(@"%@", [NSThread callStackSymbols]); ?每次崩溃日志的最后几行都像上面那样。
  • 在 Instruments 中,从菜单栏中选择 View > Extended Detail。然后,当您点击引用计数日志中的某个事件时,扩展的详细视图将向您显示事件发生时的调用堆栈(堆栈跟踪)。
  • @robmayoff 是的,我已经检查过了,但没有看到任何特别有用的东西。最后几个调用是 objectHash、hashProbe、[NSConcreteHashTable rehashAround]、[NSConcreteHashTable removeItem] 等。

标签: objective-c ios5 automatic-ref-counting exc-bad-access


【解决方案1】:

@robmayoff 是的,我已经检查过了,但没有看到任何特别有用的东西。最后几个调用是 objectHash、hashProbe、[NSConcreteHashTable rehashAround]、[NSConcreteHashTable removeItem] 等。

这实际上有点用处。这告诉我们一个集合,可能是一个NSDictionary,但也可能是一个NSSet,正在被销毁。从您之前的信息来看,它似乎是在 nib 实例化过程中创建的自动发布集合(因此可能是 CoursesFirstViewController 的 ivar)。考虑到这些症状,无论如何我都会去那里寻找,但崩溃似乎证实了这一点。

一般建议是审核任何 __bridge 转换或 unsafe_unretained 属性。

另一个预感是您以违反 Cocoa 内存管理的方式命名方法。最可能的错误命名是您有一个以newcopy 开头的属性。如果您有 ARC 代码调用错误命名的非 ARC 代码,这肯定是个问题。

【讨论】:

  • 我现在 80% 确定是搜索功能造成了麻烦,尽管我还没有弄清楚到底是怎么回事。我将查看 searchResults 集合,看看它们是否有问题。谢谢!
  • 谢谢 Rob,是一些 NSDictionary 给我带来了麻烦。我没有弄清楚它到底出了什么问题,但是我重写了搜索功能,现在一切都很好。赞赏!
  • 天哪。我们有一个名为“newRequirements”的核心数据属性。在我们使用 XCode5 构建之前,它运行良好。然后我们到处都是僵尸。将 CoreData 模型属性重命名为“nextRequirements”对其进行了排序。花了大约 6 个小时来发现和修复那个。感谢您的提示。
【解决方案2】:

我怀疑您的某个属性在本应为“强”时被标记为“弱”,并且超出范围并在您访问它之前被释放。在这种情况下,ARC 无法拯救你,你会得到上述随机崩溃行为。

如果您没有任何运气找到它,我会求助于对您项目的“弱”属性进行全局搜索,并仔细检查每个属性,以确保它不是您希望闲逛的东西。这很乏味,但老实说不需要那么长时间,而且有时会出现不止一个错误。

【讨论】:

  • 当对象被释放时,标记为weak 的属性设置为 nil,因此在这种情况下您不应该看到僵尸消息。标记为assignunsafe_unretained 的属性可能指向僵尸。
  • 实际上 ARC 确实可以防止这种情况下的崩溃,因为它在释放时将弱引用指针归零。
  • 我认为与我的 CoursesFirstViewController 相关的所有内容都很强大。只有 Xcode 创建的一些 IBOutlets 很弱,它们都在其他一些函数中,所以不应该是原因。 (如果我至少一次不访问 CFVC,那么一切似乎都很好。)
【解决方案3】:

我从您的 Instruments 输出中得知僵尸对象的类型为 CoursesFirstViewController。我们经常使用视图控制器作为其他对象的委托,并且大多数具有委托的对象不保留它们的委托。

我假设您没有使用任何unsafe_unretained 属性或变量,或任何retain-type 属性。所以我假设你的所有对象都没有对CoursesFirstViewController 僵尸保持悬空引用。

由于系统库必须使用非 ARC 代码,它们不使用 ARC 的弱引用。因此,如果某个系统对象有一个CoursesFirstViewController 作为它的委托,并且CoursesFirstViewController 被销毁但系统对象没有被销毁,那么系统对象就会留下对被销毁对象的悬空引用。

因此,请检查您是否使用CoursesFirstViewController 作为任何系统对象的委托。如果是这样,您确定这些对象不会比CoursesFirstViewController 寿命长吗?

【讨论】:

  • 我使用CoursesFirstViewController 作为UISearchBarDelegateUISearchDisplayDelegate。但我认为,由于这些是视图控制器 UI 的组件,它们不应该比CoursesFirstViewController 寿命长吗?唯一的另一件事是我正在使用ASIHttpRequest,它没有使用ARC,并且我有一些本地ASIHTTPRequest 变量,其代表设置为CoursesFirstViewController。但我也在程序中的其他地方使用ASIHTTPRequest,它们似乎很好,所以我对此不太确定..
  • 通常,视图控制器的视图层次结构中的 UI 元素在视图控制器被销毁时被销毁。但是您可能会保留对其中之一的引用。 (你应该知道你是不是。)我不熟悉ASIHttpRequest,所以我当然建议调查这些对象是否可以勾勒出视图控制器。 ASIHttpRequest 是否会产生一个线程,或者注册一些网络活动的异步通知?这可能会保留ASIHttpRequest,让它比视图控制器更长寿。
  • 我刚刚修改了ASIHTTPRequest 对象,使它们不再有CoursesFirstViewController 作为他们的代表。然而崩溃仍然存在。但我也不认为搜索显示控制器或搜索栏会以某种方式过活CoursesFirstViewController... :(
猜你喜欢
  • 2011-12-17
  • 1970-01-01
  • 2012-04-09
  • 2012-06-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-10
相关资源
最近更新 更多