1

私のアプリケーションでは、このメソッドはメモリ リークを示しています。リークを削除するにはどうすればよいですか?

-(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 に答える 4

4

関数の先頭で初期化するオブジェクトを実際には使用しません。

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

したがって、それらはリークしているオブジェクトのようです。

于 2009-08-24T09:26:45.553 に答える
2

[[NSString alloc] init] は完全に無意味です。より多くの作業を除いて、@"" とまったく同じものを返します。システムはほぼ確実に固定定数の空の文字列を返し、init ルーチンで [NSString alloc] を解放するため、リークする可能性は低いです。しかし、それは無意味で役に立たない悪いコードです。

それ以外は、コードは問題ないように見えます。2 番目の方法は、optionsList を「リーク」すると見なされる可能性があります。これは、単純にそれを作成し、決して解放されないためですが、作成されるのは 1 回だけなので問題ないはずです。

プログラムを実行してリーク検出を行ってから、デバッガーを中断して使用してみてください

po 0x4b2720 (リークされたオブジェクトのアドレスに置き換えます)

実際に漏れている文字列を確認します。

リークは、特に何かがキャッシュされている場合に誤検知を引き起こす可能性があることに注意してください。

于 2009-08-24T12:53:41.817 に答える
1

-1/2

@""[[[NSString alloc] init] autorelease]; [[NSString alloc] init]will leakと同等です。

ルールを覚えておいてください:init/retainでバランスを取る必要がありますautorelease/release

于 2010-04-29T04:50:24.750 に答える
1

[[NSString alloc] init];は無駄な言い回しです。最初の 2 行を削除すると、リークが解消されます。

編集:データベースから取得した2つの文字列は、保持されていない限り、autoreleasepoolが空になるとすぐに消えることに注意してください。

編集:2番目の方法について。明らかな漏れは見られません。NSCFStrings は頻繁に作成され、しばしば残ります。それは、それらが実際に漏れているという意味ではありません。私が見る限り、そのメソッドのすべては自動解放または永続的です。

于 2009-08-24T09:28:25.567 に答える