2009-08-24 4 views
1

私のアプリケーションでは、このメソッドはメモリリークを示します。リークをどのように取り除きますか?NSString関連メモリリークを削除するには?

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

} 

この方法でもリークが表示されます.....この方法には何が問題なのですか?あなたが後で他の人と、それらのオブジェクトを置き換えるよう

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

:あなたが実際にあなたが関数の先頭に初期化オブジェクトを使用していない

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

}

alt text http://www.freeimagehosting.net/uploads/5b8120982c.png

答えて

4

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

これらは、漏れているオブジェクトのようです。

+0

私はそれらの2行を削除まだleak..i iはラベル上のテキストを表示するflashcardtextを使用しています楽器 –

+0

から画像を追加してい示すいる... しかし、私は3-4で同じクラスのflashcardanswerを使用しています回...別のクラスにテキストを表示しています...もし私がflashcardanswer appから自分を削除したら。クラッシュする –

+0

プロパティが(おそらく)flashCardTextとflashCardAnswerの(無意味な)初期値を解放するので、それらは漏れません。 –

1

[[NSString alloc] init];は無駄なフレーズです。 2つの最初の行を削除すると、リークを取り除くことができます。

EDIT:データベースから取得した2つの文字列は、保持されていない限り、自動回収プールが排水されるとすぐに消滅します。

Redit:第2の方法について。明らかな漏れは見られません。 NSCFStringは多く作成され、しばしば固執します。それは彼らが実際にリークであることを意味しません。私が見ることのできるところからは、そのメソッドのすべてがオートレリースされているか、永続的であるかのいずれかです。

+0

良い点を助けるかもしれませんその上に。尋ねられた質問にあまりにも集中することができることを示すために行く:-) –

+0

このようなヘッダーファイルでプロパティを作成する必要があります @property(nonatomic、retain)NSString * flashCardText;またはこのように @property(非構造、コピー)NSString * flashCardText; –

+0

'@property(nonatomic、copy)'は、私が思い出した限り、一般的に文字列に最適と見なされます。 –

2

[[NSString alloc] init]は完全に無意味です。より多くの作業を除いて、@ ""と全く同じものを返します。システムがほぼ確実に固定の定数の空の文字列を返すので、initルーチン内の[NSString alloc]を解放するので、そのリークは起こりにくいでしょう。しかし、無意味で無駄なコードです。

それ以外は、あなたのコードはOKです。 2つ目の方法はoptionsListを "リークする"と考えられるかもしれません。単純にそれを作成し、決して解放されないからです。

は、デバッガで破り、実際に漏れているものを、文字列を参照する

経口0x4b2720(リークしたオブジェクトのアドレスに置き換え)

を使用して、あなたのプログラムを実行し、リーク検出を行ってみてください。

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

+0

+1のデバッグ方法。 – Abizern

+0

これは動作しません0x4b2720(リークされたオブジェクトのアドレスで置き換えます)gdbは何も印刷しません... –

1

-1/2

@""[[[NSString alloc] init] autorelease]; [[NSString alloc] init]に相当する漏洩します。

ルール:init/retainは、autorelease/releaseと均衡する必要があります。

関連する問題