我经常会收到一条错误,内容为*** -[NSKeyValueObservance retain]: message sent to deallocated instance 0x86c75f10
。我试过运行Zombies模板,这是它提供的截图。
它指向一个托管对象,我无法确定对象被解除分配的位置。这是编译器在每次崩溃后带我到的代码块。
- (void)setIsFavourite:(BOOL)isFavourite shouldPostToAnalytics:(BOOL)shouldPostToAnalytics;
{
// check whether we need to generate preferences objects just in time
if(!self.preferences && !self.series.preferences /*&& isFavourite*/)
{
if(self.series)
{
[self.series addPreferencesObject];
}
else
{
[self addPreferencesObject];
}
}
//Crash In here
self.preferences.isFavourite = @(isFavourite);
self.series.preferences.isFavourite = @(isFavourite);
编辑:如果您需要查看较大尺寸的图片,here是一个较大的分辨率链接。
答案 0 :(得分:0)
您使用的是手动引用计数吗?如果是这样,为什么?将您的应用转换为ARC。手动引用计数充其量是痛苦的,ARC更好。
我是一位经验丰富的iOS和Mac OS开发人员,可以做任何一种,但我更喜欢ARC。它不那么繁琐且容易出错。
Xcode内置了一个功能,可以将项目转换为ARC。你可能不得不做一些清理,但这是值得的。
如果你这样做,你的问题可能就会消失。
至于具体细节,您的截图太小,无法读取。如果你想让某人试图找出正在发生的事情,你需要张贴一张全尺寸的图片。
然而,从广义上讲,我觉得你有一个自动释放错误。
在手动引用计数代码中,许多系统方法返回“自动释放”的对象。这意味着当你收到它们时,它们的保留计数是正数(通常为1)所以它们会保持不变。但是,它们已添加到“自动释放池”中,这意味着如果没有人首先保留它们,它们将在下一次通过事件循环时释放。
当您收到自动释放的对象时,您应该接受它将在您当前方法返回后释放,或者保留它。
如果您尝试使用手动引用计数编写Core Data代码并且不理解这一点,那么您就是在为自己设置失败。
核心数据非常复杂,在尝试编写使用它的程序之前,您应该对Cocoa内存管理有充分的了解,如果您使用手动引用计数,尤其。
答案 1 :(得分:0)
好的,我遇到了类似的问题,并找到了一种使用NSKeyValueObservance调试此类问题的方法。要调试,请执行以下操作:
-[NSKeyValueObservance _initWithObserver:property:options:context:originalObservable:]
expr (void)NSLog(@"observer <0x%p>: %@ <%p>, property: %@", $arg1, (id)NSStringFromClass((id)[(id)$arg3 class]), $arg3, (id)$arg4)
现在,您可以运行您的应用程序,并采取必要的步骤来重现崩溃。是的,您需要启用NSZombies。 注意:它会运行缓慢,您将获得大量调试输出,但是请耐心等待。最终会到达那里。
当您尝试向已释放的NSKeyValueObservance发送消息时遇到崩溃时,系统将为您提供原始对象的地址。突出显示地址,然后按cmd-e在搜索缓冲区中输入文本。然后按cmd -g在调试器输出中找到该字符串的下一个匹配项。您可能会多次找到该地址,因此请寻找observer <0x?????>
输出之后的地址。该行的输出应该告诉您正在观察哪个对象以及哪个属性。
在我的案例中,当我弄清楚了所有这些内容后,发现我正在观察一个依赖于数组中对象的综合属性,并且在特定操作期间,数组中对象的顺序发生了变化,而没有做正确的事情KVO通知,这导致了我的崩溃。