Как удалить NSString связанные утечки памяти? - PullRequest
1 голос
/ 24 августа 2009

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

-(void)getOneQuestion:(int)flashcardId categoryID:(int)categoryId
{   

    flashCardText = [[NSString alloc] init];
    flashCardAnswer=[[NSString alloc] init];
    //NSLog(@"%s %d %s", __FILE__, __LINE__, __PRETTY_FUNCTION__, __FUNCTION__);

    sqlite3 *MyDatabase;
    sqlite3_stmt *CompiledStatement=nil;
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *MyDatabasePath = [documentsDirectory stringByAppendingString:@"/flashCardDatabase.sqlite"];
    if(sqlite3_open([MyDatabasePath UTF8String],&MyDatabase) == SQLITE_OK)
    {
        sqlite3_prepare_v2(MyDatabase, "select flashCardText,flashCardAnswer,flashCardTotalOption from flashcardquestionInfo where flashCardId=? and categoryId=?", -1, &CompiledStatement, NULL);
        sqlite3_bind_int(CompiledStatement, 1, flashcardId);
        sqlite3_bind_int(CompiledStatement, 2, categoryId);
        while(sqlite3_step(CompiledStatement) == SQLITE_ROW)
        {       
            self.flashCardText = [NSString stringWithUTF8String:(char *)sqlite3_column_text(CompiledStatement,0)];
            self.flashCardAnswer= [NSString stringWithUTF8String:(char *)sqlite3_column_text(CompiledStatement,1)];
            flashCardTotalOption=[[NSNumber numberWithInt:sqlite3_column_int(CompiledStatement,2)] intValue];
        }
        sqlite3_reset(CompiledStatement);
        sqlite3_finalize(CompiledStatement);
        sqlite3_close(MyDatabase);
    }

}

этот метод также показывает утечки ..... что не так с этим методом?

-(void)getMultipleChoiceAnswer:(int)flashCardId
 {  
if(optionsList!=nil)
    [optionsList removeAllObjects];
else
    optionsList = [[NSMutableArray alloc] init];

sqlite3 *MyDatabase;
sqlite3_stmt *CompiledStatement=nil;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *MyDatabasePath = [documentsDirectory stringByAppendingString:@"/flashCardDatabase.sqlite"];
if(sqlite3_open([MyDatabasePath UTF8String],&MyDatabase) == SQLITE_OK)
{
    sqlite3_prepare_v2(MyDatabase,"select OptionText from flashCardMultipleAnswer where flashCardId=?", -1, &CompiledStatement, NULL);
    sqlite3_bind_int(CompiledStatement, 1, flashCardId);
    while(sqlite3_step(CompiledStatement) == SQLITE_ROW)
    {       
        [optionsList addObject:[NSString stringWithUTF8String:(char *)sqlite3_column_text(CompiledStatement,0)]];
    }
    sqlite3_reset(CompiledStatement);
    sqlite3_finalize(CompiledStatement);
    sqlite3_close(MyDatabase);
}   

}

альтернативный текст http://www.freeimagehosting.net/uploads/5b8120982c.png

Ответы [ 4 ]

4 голосов
/ 24 августа 2009

Вы фактически не используете объекты, которые вы инициализируете в верхней части функции:

flashCardText = [[NSString alloc] init];
flashCardAnswer=[[NSString alloc] init];

как только вы замените эти объекты другими:

self.flashCardText = [NSString stringWithUTF8String:(char *)sqlite3_column_text(CompiledStatement,0)];
self.flashCardAnswer= [NSString stringWithUTF8String:(char *)sqlite3_column_text(CompiledStatement,1)];

Так что, похоже, это объекты, которые протекают.

2 голосов
/ 24 августа 2009

[[NSString alloc] init] совершенно бессмысленно. Он вернет точно эквивалент @ "", кроме как с дополнительной работой. Это вряд ли утечка, поскольку система почти наверняка вернет вам фиксированную постоянную пустую строку, освобождая [NSString alloc] в процедуре init. Но это бессмысленный, бесполезный и плохой код.

Кроме этого, ваш код выглядит нормально. Второй метод может считаться «утечкой» optionsList просто потому, что он его создает и никогда не освобождается, а создается только один раз, поэтому с ним все должно быть в порядке.

Попробуйте запустить вашу программу и выполнить обнаружение утечек, затем включить отладчик и использовать

po 0x4b2720 (заменить на адрес утекших объектов)

чтобы увидеть, какая строка на самом деле подтекает.

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

1 голос
/ 29 апреля 2010

-1/2

@"" эквивалентно [[[NSString alloc] init] autorelease]; [[NSString alloc] init] будет течь.

Запомните правило: init/retain должно быть сбалансировано autorelease/release.

1 голос
/ 24 августа 2009

[[NSString alloc] init]; - бесполезная фраза. Удаление двух первых строк избавит от утечки.

РЕДАКТИРОВАТЬ: Обратите внимание, что две строки, которые вы извлекаете из базы данных, исчезнут, как только автозапуск будет очищен, если они не будут сохранены.

Redit: относительно второго метода; Я не вижу никаких очевидных утечек. NSCFStrings создаются много и часто остаются без дела. Это не значит, что они на самом деле являются утечками. Из того, что я вижу, все в этом методе является либо автоматически выпущенным, либо постоянным.

...