Должен ли я использовать AutoreleasePool? - PullRequest
0 голосов
/ 07 апреля 2011

Привет всем У меня есть класс, который работает с базой данных sqlite в моем приложении.Здесь вы можете увидеть одну из функций, которые я написал.Эта функция должна получить количество элементов, в которых значение столбца равно заданному значению.

 + (int) GetCountOfItems: (NSString*) byColumn {
        // Autorelease Pool.
        NSAutoreleasePool* pool = [[NSAutoreleasePool alloc]init];
        // Create Sqlite query string.
        NSString* sqliteQuery = [NSString stringWithFormat:@"SELECT COUNT(*) FROM [Articles] WHERE %@ = 1", byColumn];
        NSLog(@"GetCountOfItems query string is: %@", sqliteQuery);
        // Create statement.
        sqlite3_stmt*   stmt;
        int articleCount = 0;

        if( sqlite3_prepare_v2(database, [sqliteQuery UTF8String], -1, &stmt, NULL) == SQLITE_OK ) {
            if( sqlite3_step(stmt) == SQLITE_ROW )
                articleCount  = sqlite3_column_int(stmt, 0); 
        }
        else NSLog(@"Failed from GetCountOfItems. Error is:  %c", sqlite3_errmsg(database));

        // Finalize.
        sqlite3_finalize(stmt);

        // Release Pool.
        [pool release];

        return articleCount;
    }

Я хочу знать, корректна ли эта функция, например, следует ли мне использовать NSAutoreleasePool * pool =[[NSAutoreleasePool alloc] init];???? А как это может мне помочь с памятью?

Ответы [ 4 ]

3 голосов
/ 07 апреля 2011

Если этот код выполняется в главном потоке, то нет, вам не нужно.

Если этот код выполняется в другом потоке, тогда да, вы должны.

2 голосов
/ 07 апреля 2011

На основе следующего описания (в Руководство по программированию управления памятью ):

Application Kit автоматически создает пул в начале цикла события (или события -цикл итерации), например событие нажатия мыши, и истощает его в конце, так что ваш код обычно не должен беспокоиться о них.Однако в трех случаях вы можете использовать свои собственные пулы автоматического выпуска:

Если вы пишете программу, не основанную на наборе приложений, например, инструмент командной строки, встроенныхв поддержку авто-релизных пулов;вы должны создать их самостоятельно.

Если вы создаете вторичный поток, вы должны создать свой собственный пул автоматического выпуска, как только поток начнет выполняться;в противном случае вы будете пропускать предметы.(Подробности см. В разделе «Пулы и потоки автоматического освобождения».)

Если вы пишете цикл, который создает много временных объектов, вы можете создать пул автоматического освобождения внутри цикла, чтобы избавиться от этих объектов перед следующей итерацией.Это может помочь уменьшить максимальный объем памяти приложения.

Я бы сказал, не беспокойтесь, просто выделите любые объекты по мере необходимости, а затем отпустите их, прежде чем вернуться из метода.

Также см. Этот пост .

1 голос
/ 07 апреля 2011

Как правило, мне нужно использовать пулы автоматического выпуска только при создании потоков.

Вам необходимо добавить операторы sqlite3_mprintf и sqlite3_free.

    + (int) GetCountOfItems: (NSString*) byColumn {

        NSString* sqliteQuery = @"SELECT COUNT(*) FROM [Articles] WHERE %q = 1";
        char *sql = sqlite3_mprintf((char*)[sqliteQuery UTF8String], (char*)[byColumn UTF8String]);  //Add this statement
        sqlite3_stmt*   stmt;
        int articleCount = 0;

        if( sqlite3_prepare_v2(database, sql, -1, &stmt, NULL) == SQLITE_OK ) {
            if( sqlite3_step(stmt) == SQLITE_ROW )
                articleCount  = sqlite3_column_int(stmt, 0); 
        }
        else NSLog(@"Failed from GetCountOfItems. Error is:  %c", sqlite3_errmsg(database));

        sqlite3_finalize(stmt);
        sqlite3_free(sql);    //Add this statement

        return articleCount;
    }
0 голосов
/ 07 апреля 2011

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

В среде с подсчетом ссылок (в отличие от среды, в которой используется сборщик мусора), объект NSAutoreleasePool содержит объекты, которые получилисообщение об автозапуске, и когда оно истощено, оно отправляет сообщение об освобождении каждому из этих объектов.Таким образом, отправка авто-выпуска вместо выпуска объекта продлевает время жизни этого объекта, по крайней мере, до тех пор, пока сам пул не будет очищен (это может быть дольше, если объект впоследствии будет сохранен).Объект может быть помещен в один и тот же пул несколько раз, и в этом случае он получает сообщение о выпуске каждый раз, когда он был помещен в пул.

В среде с подсчетом ссылок Cocoa ожидает, что будет пул авто-выпускавсегда доступен.Если пул недоступен, автоматически выпущенные объекты не освобождаются, и вы теряете память.В этой ситуации ваша программа, как правило, регистрирует подходящие предупреждающие сообщения.

Application Kit создает пул автоматического выпуска в главном потоке в начале каждого цикла цикла событий и сливает его в конце, освобождая тем самымлюбые автоматически выпущенные объекты, сгенерированные во время обработки события.Если вы используете Application Kit, вам, как правило, не нужно создавать свои собственные пулы.Однако, если ваше приложение создает много временных автоматически выпущенных объектов в цикле событий, может быть полезно создать «локальные» пулы автоматического выпуска, чтобы помочь минимизировать пиковый объем памяти.

Вы создаете объект NSAutoreleasePool с помощьюобычные сообщения alloc и init и распоряжаться ими с помощью стока (или release - чтобы понять разницу, см. «Сборка мусора»).Поскольку вы не можете сохранить пул авто-релиза (или его авто-релиз - см. «Сохранение и авто-релиз»), в конечном итоге слив пула приводит к его освобождению.Вы всегда должны сливать пул авто-релиза в том же контексте (вызов метода или функции или тела цикла), в котором он был создан.См. Autorelease Pools для получения более подробной информации.

Каждый поток (включая основной поток) поддерживает свой собственный стек объектов NSAutoreleasePool (см. «Потоки»).По мере создания новых пулов они добавляются на вершину стека.Когда пулы освобождаются, они удаляются из стека.Автоматически освобожденные объекты помещаются в верхний пул автоматического выпуска для текущего потока.Когда поток завершается, он автоматически удаляет все пулы автоматического выпуска, связанные с ним.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...