消息发送到解除分配的实例错误

时间:2015-02-10 23:14:09

标签: ios objective-c

我经常会收到一条错误,内容为*** -[NSKeyValueObservance retain]: message sent to deallocated instance 0x86c75f10。我试过运行Zombies模板,这是它提供的截图。

enter image description here

它指向一个托管对象,我无法确定对象被解除分配的位置。这是编译器在每次崩溃后带我到的代码块。

- (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是一个较大的分辨率链接。

2 个答案:

答案 0 :(得分:0)

您使用的是手动引用计数吗?如果是这样,为什么?将您的应用转换为ARC。手动引用计数充其量是痛苦的,ARC更好。

我是一位经验丰富的iOS和Mac OS开发人员,可以做任何一种,但我更喜欢ARC。它不那么繁琐且容易出错。

Xcode内置了一个功能,可以将项目转换为ARC。你可能不得不做一些清理,但这是值得的。

如果你这样做,你的问题可能就会消失。

至于具体细节,您的截图太小,无法读取。如果你想让某人试图找出正在发生的事情,你需要张贴一张全尺寸的图片。

然而,从广义上讲,我觉得你有一个自动释放错误。

在手动引用计数代码中,许多系统方法返回“自动释放”的对象。这意味着当你收到它们时,它们的保留计数是正数(通常为1)所以它们会保持不变。但是,它们已添加到“自动释放池”中,这意味着如果没有人首先保留它们,它们将在下一次通过事件循环时释放。

当您收到自动释放的对象时,您应该接受它将在您当前方法返回后释放,或者保留它。

如果您尝试使用手动引用计数编写Core Data代码并且不理解这一点,那么您就是在为自己设置失败。

核心数据非常复杂,在尝试编写使用它的程序之前,您应该对Cocoa内存管理有充分的了解,如果您使用手动引用计数,尤其

答案 1 :(得分:0)

好的,我遇到了类似的问题,并找到了一种使用NSKeyValueObservance调试此类问题的方法。要调试,请执行以下操作:

  1. 在Xcode中,打开“断点导航器”。
  2. 使用以下命令添加新的符号断点: -[NSKeyValueObservance _initWithObserver:property:options:context:originalObservable:]
  3. 在该断点处,添加一个动作并将其设置为“ Debugger Command”。
  4. 设置以下命令:expr (void)NSLog(@"observer <0x%p>: %@ <%p>, property: %@", $arg1, (id)NSStringFromClass((id)[(id)$arg3 class]), $arg3, (id)$arg4)
  5. 单击“评估表达式后自动继续”。

现在,您可以运行您的应用程序,并采取必要的步骤来重现崩溃。是的,您需要启用NSZombies。 注意:它会运行缓慢,您将获得大量调试输出,但是请耐心等待。最终会到达那里。

当您尝试向已释放的NSKeyValueObservance发送消息时遇到崩溃时,系统将为您提供原始对象的地址。突出显示地址,然后按cmd-e在搜索缓冲区中输入文本。然后按cmd -g在调试器输出中找到该字符串的下一个匹配项。您可能会多次找到该地址,因此请寻找observer <0x?????>输出之后的地址。该行的输出应该告诉您正在观察哪个对象以及哪个属性。

在我的案例中,当我弄清楚了所有这些内容后,发现我正在观察一个依赖于数组中对象的综合属性,并且在特定操作期间,数组中对象的顺序发生了变化,而没有做正确的事情KVO通知,这导致了我的崩溃。