GuybrushThreepwood
GuybrushThreepwood

Reputation: 5616

App Crashing When Calling Release on Autorelease Pool - Timing Issue ? iPhone

I have the following method in my app :

- (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];

}

The loadFromFileData method calls the following code which loads data. :

- (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]];
        }
    }
}
}

Since this method is called several times while the data loads, each time mallocing memory for the mesh->vertices struct, I have created a pointerStorage array where I store the pointer to the malloced memory.

The app then displays a 3D object using OpenGL ES. When the user presses a Main Menu button, I then free up the pointerStorageArray as follows :

- (void) freeUpMallocedMemory

for (NSValue * value in pointerStorageArray) {

    free(value);

}

The problem is that the app then crashes during this process. All I get is the EXC_BAD_ACCESSS error message and a pointer to the following line of code in the loadModel method above :

[pool release];

Nothing in the stack trace. I have also tried turning on NSZombie, NSAutoreleaseTrackFreedObjectCheck and NSDebugEnabled, but I still don't get any additional information.

The odd thing is that if I put a delay on the button of 2 seconds (i.e only trigger the freeUpMallocedMemory method after 2 seconds), the app no longer crashes and works fine.

Can anyone suggest what might be causing this - really confused and have already spent a few days troubleshooting.

Thank you !

Upvotes: 1

Views: 605

Answers (1)

Simon Lee
Simon Lee

Reputation: 22334

You are over-releasing... the values in pointerStorageArray are created via a convenience method and as such don't need releasing, simply removing them from the array will dispose of them.

Upvotes: 3

Related Questions