在自动释放池上调用释放时应用程序崩溃 - 时间问题?苹果手机

时间:2011-12-20 14:19:39

标签: iphone objective-c xcode memory-management autorelease

我的应用程序中有以下方法:

- (void) loadModel {
// Runs in a seperate thread so we need to create an additional NSAutoreleasePool
pool = [[NSAutoreleasePool alloc] init];

NSData *getData = [activeModelInfo getFileData];

if (getData) {
    if ([activeModel loadFromFileData:daeData]) {
        [activeModel reset];
        [mainViewController performSelectorOnMainThread:@selector(showModelView) withObject:nil waitUntilDone:NO];
    }
    else {

    }
}
else {

}

[pool release];

}

loadFromFileData方法调用以下加载数据的代码。 :

- (void) loadVerticesFromSource:(NSString*)verticesSourceId meshNode:(TBXMLElement*)meshNode intoMesh: (Mesh3D*) mesh {

NSLog(@"Getting Vertices for Source %@",verticesSourceId);

FloatArray *floatArray =  [self getFloatArrayFromSource: verticesSourceId meshNode: meshNode];

if (floatArray) {
[daeFloatArray addObject:floatArray];
}

if (floatArray) {
    if ([floatArray.array count] % 3 != 0) {
        NSLog(@"Float array length not divisible by 3!");
    }
    else {
        mesh->verticesCount = [floatArray.array count] / 3;
        mesh->vertices = malloc(sizeof(Vector3D) * mesh->verticesCount);
        for (int i=0; i<mesh->verticesCount; i++) {
            mesh->vertices[i].x = [[floatArray.array objectAtIndex:(i*3)] floatValue];
            mesh->vertices[i].y = [[floatArray.array objectAtIndex:(i*3)+1] floatValue];
            mesh->vertices[i].z = [[floatArray.array objectAtIndex:(i*3)+2] floatValue];

            // update extents information
            if (!extents.pointDefined || mesh->vertices[i].x < extents.minX) extents.minX = mesh->vertices[i].x;
            else if (!extents.pointDefined || mesh->vertices[i].x > extents.maxX) extents.maxX = mesh->vertices[i].x;
            if (!extents.pointDefined || mesh->vertices[i].y < extents.minY) extents.minY = mesh->vertices[i].y;
            else if (!extents.pointDefined || mesh->vertices[i].y > extents.maxY) extents.maxY = mesh->vertices[i].y;
            if (!extents.pointDefined || mesh->vertices[i].z < extents.minZ) extents.minZ = mesh->vertices[i].z;
            else if (!extents.pointDefined || mesh->vertices[i].z > extents.maxZ) extents.maxZ = mesh->vertices[i].z;
            if (!extents.pointDefined) extents.pointDefined = YES;

            [pointerStorageArray addObject:[NSValue valueWithPointer:mesh->vertices]];
        }
    }
}
}

由于在数据加载时多次调用此方法,每次mallocing内存为mesh-&gt; vertices结构,我创建了一个pointerStorage数组,我将指针存储到malloced内存。

然后,应用程序使用OpenGL ES显示3D对象。当用户按下主菜单按钮时,我将释放指针存储阵列,如下所示:

- (void) freeUpMallocedMemory

for (NSValue * value in pointerStorageArray) {

    free(value);

}

问题是应用程序然后在此过程中崩溃。我得到的是EXC_BAD_ACCESSS错误消息和上面loadModel方法中以下代码行的指针:

[pool release];

堆栈跟踪中没有任何内容。我也试过打开NSZombie,NSAutoreleaseTrackFreedObjectCheck和NSDebugEnabled,但我仍然没有得到任何其他信息。

奇怪的是,如果我在2秒的按钮上放一个延迟(即仅在2秒后触发freeUpMallocedMemory方法),该应用程序不再崩溃并且工作正常。

任何人都可以建议可能造成这种情况的原因 - 真的很困惑,已经花了几天时间进行故障排除。

谢谢!

1 个答案:

答案 0 :(得分:3)

你过度释放...... pointerStorageArray中的值是通过一个方便的方法创建的,因此不需要释放,只需将它们从数组中删除就可以处理它们。