Сбой приложения при вызове релиза из пула автоматического выпуска - проблема синхронизации? iPhone - PullRequest
1 голос
/ 20 декабря 2011

В моем приложении есть следующий метод:

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

Поскольку этот метод вызывается несколько раз при загрузке данных, каждый раз, когда происходит неправильное использование памяти для структуры mesh-> vertices, я создал массив pointerStorage, в котором хранится указатель на неправильную память.

Затем приложение отображает 3D-объект с помощью OpenGL ES. Когда пользователь нажимает кнопку главного меню, я освобождаю pointerStorageArray следующим образом:

- (void) freeUpMallocedMemory

for (NSValue * value in pointerStorageArray) {

    free(value);

}

Проблема заключается в том, что приложение завершает работу во время этого процесса. Все, что я получаю, это сообщение об ошибке EXC_BAD_ACCESSS и указатель на следующую строку кода в методе loadModel выше:

[pool release];

Ничего в трассировке стека. Я также пытался включить NSZombie, NSAutoreleaseTrackFreedObjectCheck и NSDebugEnabled, но до сих пор не получаю никакой дополнительной информации.

Странно то, что если я установлю задержку на кнопку в 2 секунды (т. Е. Вызов метода freeUpMallocedMemory только через 2 секунды), приложение больше не будет аварийно завершать работу и работает нормально.

Может кто-нибудь подсказать, что может быть причиной этого - действительно запутался и уже потратил несколько дней на устранение неисправностей.

Спасибо!

1 Ответ

3 голосов
/ 20 декабря 2011

Вы перевыпускаете ... значения в pointerStorageArray создаются с помощью удобного метода и, как таковые, не требуют освобождения, просто удалив их из массива, вы избавитесь от них.

...