已释放对象的校验和不正确.应用程序出现异常崩溃



我已经在一个应用程序上工作了一段时间。。到目前为止,我一直在运行它,同时调试器已经连接,它运行得很好(因为NSZombies已经启用)。。。

我最近注意到,当推到一个新的视图控制器时,应用程序会崩溃。我以为这是一个简单的解决方案,但到目前为止,它看起来并不是那样的。

该应用程序通过以下操作工作(此方法以前也工作过)。。。

  1. 用户选择视图
  2. RootViewController已推送到tableViewController
  3. 用户选择项目
  4. ViewController已初始化和配置
  5. 导航控制器推送到新的ViewController

现在,如果我将我的方案配置为启用NSZombies,那么这很好。。我的新视图加载了vola,它起作用了。

然而。。如果我不这样做,应用程序就会崩溃!

在控制台窗口中,我得到以下错误:

2012-01-17 19:51:14.599 DrivingInstructor[61946:17003] -[PhotoViewController loadView]
2012-01-17 19:51:14.654 DrivingInstructor[61946:17003] -[PhotoViewController viewWillAppear:]
DrivingInstructor(61946,0xac6ad2c0) malloc: *** error for object 0x92b0e14: incorrect checksum for freed object - object was probably modified after being freed.
*** set a breakpoint in malloc_error_break to debug

所以我设置了malloc_error_break来查看发生了什么。。。没有什么区别,我仍然收到上面的错误(注意前两条消息显示我的新ViewController正在初始化)

如果我在崩溃后运行回溯。。这是我的输出:

#0  0x956a9c97 in malloc_error_break ()
#1  0x9566b4ce in szone_error ()
#2  0x9566b54e in free_list_checksum_botch ()
#3  0x9566b63f in tiny_free_list_remove_ptr ()
#4  0x956702b1 in szone_free ()
#5  0x01f30a98 in __CFAllocatorSystemDeallocate ()
#6  0x01f2978a in CFAllocatorDeallocate ()
#7  0x01f30960 in CFRelease ()
#8  0x01fe6b4f in __CFDictionaryStandardReleaseKey ()
#9  0x01f474df in __CFBasicHashDrain ()
#10 0x01f304e3 in CFRelease ()
#11 0x02011e94 in -[__NSArrayM dealloc] ()
#12 0x021c8e4d in _objc_rootRelease ()
#13 0x021c8e10 in objc_release ()
#14 0x021c9c60 in (anonymous namespace)::AutoreleasePoolPage::pop ()
#15 0x01f58ed8 in _CFAutoreleasePoolPop ()
#16 0x015f08ce in __NSFireDelayedPerform ()
#17 0x01ff8966 in __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ ()
#18 0x01ff8407 in __CFRunLoopDoTimer ()
#19 0x01f5b7c0 in __CFRunLoopRun ()
#20 0x01f5adb4 in CFRunLoopRunSpecific ()
#21 0x01f5accb in CFRunLoopRunInMode ()
#22 0x023e2879 in GSEventRunModal ()
#23 0x023e293e in GSEventRun ()
#24 0x00cd8a9b in UIApplicationMain ()
#25 0x00002149 in main (argc=1, argv=0xbffff5d4) at main.m:14

我还应该指出。。。我最初认为这是由于我运行了一个后台线程,在ui加载时为我调整图像大小,所以不会因为我的第一个崩溃日志显示它在我的图像处理类中的某一行崩溃而冻结,但在无法对其进行排序并注释出调整图像大小的函数(在后台线程上运行)之后。。现在应用程序崩溃了,我甚至没有调用那个线程!

我不知道发生了什么,因为我最初的崩溃日志告诉我,在崩溃发生时,在后台线程上使用UIGraphics是一个问题。。。

现在它只是崩溃:S

下面是我的崩溃日志:

(当我超过3k个字符的限制时,粘贴标签)http://pastebin.com/dGF7QdeH

我会将代码共享到发生此问题的应用程序,但我不知道它发生在哪里,所以我无法向您显示:s

据我所见,调用了viewWillAppear:函数,这样我就可以设置我的视图,但它在我真正按下它之前崩溃了,但视图的设置没有什么异常,因为自上一个工作版本以来,我唯一修改的代码是设置我的视图(运行良好)

如果有人能帮我,我将非常感激。。。我一整天都在为此感到压力,在这里发帖是我的最后手段(在我去developer.apple.com之前)

感谢您的阅读,如果您需要更多信息,请告诉我。

利亚姆

首先,找出对象是0x92b0e14。(或者调试器中显示的任何地址。)一旦你知道它是什么对象,就在释放它的任何地方设置断点,并在出现错误的地方设置断点。当你在遇到错误之前点击发布时,你就会看到问题是什么。

可能是你永远不会保留这个对象,如果它在自动发布后被更改,可能会得到同样的结果。在这种情况下,实现一个保留/释放方案,使该对象保持活动状态,直到您完成它。

您在主线程上冲洗了一些东西,而后台线程过去常常先在它上面绊倒。

当所有其他操作都失败时,可以使用二进制搜索来查找问题。创建一个新的#define,如SEARCH_BUG=1,然后使用#ifdef SEARCH_BUG注释掉大量代码。让僵尸打开并启用涂鸦,以及其他一切都可能比没有它更快地发现漏洞。

这是一个iPhone应用程序,在模拟器中运行,在硬件(iPad等)上运行,也许问题会更早地在真实硬件或模拟器中显现出来。

这个堆栈看起来确实有些东西被过度释放了。(如果你真的打开了僵尸检测,这种可能性就不大了。)

我不知道这是否有帮助,但有几次我遇到malloc错误,同一视图控制器类的两个实例无意中存在于我的视图控制器层次结构中。尝试将NSLog(@"init: %@", self);放在视图控制器的init()中,将NSLog(@"dealloc: %@", self);放在它们的dealloc()中,然后比较类名和实例地址。

我在Apple开源上找到了函数free_list_checksum_botch()。

https://opensource.apple.com/source/Libc/Libc-825.26/gen/magazine_malloc.c

它试图放入错误日志"释放对象的校验和不正确-对象可能在释放后被修改。"