【问题标题】:Objc memory crash with autorelase使用 autorelase 导致 Objc 内存崩溃
【发布时间】:2010-09-06 03:52:52
【问题描述】:

我一直在寻找我的代码,但找不到这次崩溃的根源: 我正在尝试使用 NSKeyedUnarchiver 解码一个对象,它每次都会崩溃并说:

*** __NSAutoreleaseFreedObject(): release of previously deallocated object (0x1008ad200) ignored
*** __NSAutoreleaseFreedObject(): release of previously deallocated object (0x1008ab200) ignored
*** __NSAutoreleaseFreedObject(): release of previously deallocated object (0x1008a8c00) ignored

我很糟糕,initWithCoder 没有被调用的原因是 [super initWithCoder:]; 有问题。这仍然让我发疯。我看了看,指针和 NSData 对象出了什么问题:

    vertices = malloc(size_point3D * vertexCount);
    textureCoords = malloc(size_point2D * textureCount);
    normals = malloc(size_point3D * normalCount);
    faces = malloc(sizeof(GLuint) * faceCount);


    NSData *vertexData = [[NSData alloc] initWithData:[coder decodeObjectForKey:@"vertices"]];
    NSData *textureData = [[NSData alloc] initWithData:[coder decodeObjectForKey:@"textureCoords"]];
    NSData *normalData = [[NSData alloc] initWithData:[coder decodeObjectForKey:@"normals"]];
    NSData *faceData = [[NSData alloc] initWithData:[coder decodeObjectForKey:@"faces"]];


    memcpy(vertices, [vertexData bytes],  sizeof(point3D) * vertexCount);
    memcpy(textureCoords, [textureData bytes], sizeof(point2D) * textureCount);
    memcpy(normals, [normalData bytes], sizeof(point3D) * normalCount);
    memcpy(faces, [faceData bytes], sizeof(GLuint) * faceCount);

    [vertexData release];
    [textureData release];
    [normalData release];
    [faceData release];

我已尝试保留这部分中的所有内容(甚至是字符串),但没有帮助。

【问题讨论】:

  • 嗯,但它的堆栈很深
  • 看起来你正在重新定义模型。 path 是 ivar 吗?我认为第 1 步将准确地确定哪个对象试图被释放两次。代码这么少,有点棘手。
  • 嗯,它的工作原理有点令人困惑,不,当你从文件加载模型时,我基本上不是,它使用 NSKeyedUnarchiver 对其进行解码并将数据复制到自身中,相信我这在垃圾收集时有效打开,它甚至可以在 iPhone 上运行。
  • 您的initWithCoder: 是什么样的?似乎这就是错误出现的地方。相当不错的钱,这不是 Cocoa 中的错误。在托管内存而不是垃圾回收下会发生错误的原因是垃圾回收会阻止您释放仍然被引用的对象,这就是导致此类错误的原因。
  • 我在里面放了一个断点,在它被调用之前它就崩溃了!

标签: objective-c memory crash


【解决方案1】:

这是一个难以解决的问题,部分原因是调试内存的行为不一致。

我有 2 个课程 JGStaticModelJGModel。出于某种原因,取消存档者会随机选择其中一个,因此有时initWithCoder 被发送到JGModel 而不是JGStaticModel。这让我认为它没有被调用。此外,由于它们的结构略有不同,因此出现了问题并崩溃了。我遇到自动释放问题的原因是我在JGStaticModel 中修补了一些内存问题,但没有在JGModel 中修补,所以它会在内存上崩溃,因为我没有在那里修复它。

感谢大家的帮助!

【讨论】:

    【解决方案2】:

    尝试打开NSZombieEnabled,这应该可以帮助您找到问题。

    【讨论】:

      【解决方案3】:

      如果工具(运行 -> 使用性能工具运行)和 NSZombiesEnabled 都没有帮助,您可以覆盖导致异常的类的 - (id)retain 和 - (void)release 方法。调用超级实现并记录保留/释放。您可以中断此方法以查看调用堆栈。这种方式并不漂亮,但是,它帮助我弄清楚了额外的释放/自动释放调用在哪里

      【讨论】:

        【解决方案4】:

        这个问题很容易用here给出的解决方案来解决。

        相关部分是:

        如果名为“NSAutoreleaseHaltOnFreedObject”的环境变量设置为字符串值为“YES”,该函数将自动在调试器中中断

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-11-22
          • 2016-02-21
          • 1970-01-01
          • 2022-01-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-12-17
          相关资源
          最近更新 更多