Objc内存崩溃与自动释放池相关

3

我在我的代码中到处寻找这个崩溃的源头:我正在尝试使用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];

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

嗯,可以,但这是一个相当深的堆栈。 - Justin Meiners
看起来你正在重新定义模型。而 path 是一个实例变量吗?我认为第一步是确定哪个对象试图被释放两次。由于可用的代码很少,这有点棘手。 - taber
嗯,或许尝试在释放对象后将每个对象设置为nil以确保另一个线程不再尝试访问它们。 - taber
我尝试过类似的东西,但就像我说的那样,我将它们隔离开来,以便没有其他东西接触它们,只是这样做。 - Justin Meiners
@Chuck,是的,我知道,但如果它崩溃的点是在没有自动释放对象存在的地方,并且它在苹果的代码内部崩溃,我开始怀疑他们是否为此编写了良好的内存管理。 - Justin Meiners
显示剩余3条评论
4个回答

2
这个问题很难解决,部分原因是由于调试内存的行为不一致。
我有两个类 JGStaticModel 和 JGModel。由于某种原因,未归档器会随机选择其中一个,因此有时候 initWithCoder 会被发送到 JGModel 而不是 JGStaticModel。这让我认为它没有被调用。另外,由于它们的结构略有不同,所以会出现问题并崩溃。我遇到 autorelease 的问题是因为我修补了 JGStaticModel 中的一些内存问题,但没有在 JGModel 中修复,因此在那里仍会崩溃。
感谢所有的帮助!

1

0
如果没有工具(运行 -> 使用性能工具运行)和启用NSZombiesEnabled有帮助,您可以覆盖导致异常的类的- (id)retain和- (void)release方法。调用超级实现并记录保留/释放。您可以在这些方法中断点以查看调用堆栈。这种方式不太美观,但是它帮助我几次找出额外的释放/自动释放调用的位置。

0

这个问题可以通过这里提供的解决方案很容易解决。

相关部分如下:

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接