2009-08-24 6 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); 
    } 

} 

이 방법은 또한 누출을 보여줍니다 .....이 방법에 문제가 있습니까?

-(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

당신은 실제로 함수의 상단에 당신이 초기화 객체를 사용하지 않는 : 당신이 나중에 다른 사람과 해당 개체를 교체로

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

그래서 이러한 것들이 새는 개체 인 것 같습니다.

+0

나는 그 두 줄을 제거하지만 여전히 leak..i 내가 레이블에 텍스트를 표시하는 flashcardtext을 사용하고 악기 –

+0

을에서 사진을 추가하고 보여주는 ... 하지만 난 3-4에서 같은 클래스에 flashcardanswer을 사용하고있다 타임스...다른 클래스에 텍스트를 표시하는 경우 ... flashcardanswer 앱에서 본인을 삭제하면됩니다. 충돌이 발생합니다 –

+0

flashCardText 및 flashCardAnswer의 초기 값을 속성이 (아마도) 공개하지 않으므로 누출되지 않습니다. –

1

[[NSString alloc] init];은 쓸모없는 문구입니다. 두 개의 첫 번째 줄을 제거하면 누설을 제거 할 수 있습니다.

EDIT : 데이터베이스에서 가져온 두 개의 문자열이 유지되는 경우를 제외하고는 자동 복구 풀이 비워지면 사라지게됨에 유의하십시오.

Redit : 두 번째 방법에 관해서; 나는 명백한 누출을 볼 수 없다. NSCFString은 많이 만들어지고 종종 고정되어 있습니다. 그렇다고 실제로 누출 된 것은 아닙니다. 내가 볼 수 있듯이, 그 방법의 모든 것은 자동 릴리즈되거나 영구적이다.

+0

좋은 점은 autorelease에 관한, 내가 데리러 가지 않았다 그걸로. 가는 질문에 너무 많이 집중할 수 있음을 보여 주려고 :-) –

+0

이렇게 헤더 파일에 속성을 만들어야합니다. @property (nonatomic, retain) NSString * flashCardText; 또는 이와같이 @property (nonatomic, copy) NSString * flashCardText; –

+0

'@property (nonatomic, copy)'는 일반적으로 문자열에 가장 적합하다고 여겨진다. –

2

[[NSString alloc] init]은 완전히 무의미합니다. 더 많은 작업을 제외하면 정확히 "@"과 동등한 것을 반환합니다. 그 시스템은 거의 확실하게 당신에게 고정 상수 빈 문자열을 반환 할 것이기 때문에 누출 될 것 같지 않다. 초기화 루틴에서 [NSString alloc]을 해제한다. 그러나 그것은 무의미하고 쓸모없고 나쁜 코드입니다.

이외의 코드는 정상적으로 보입니다. 두 번째 방법은 optionsList를 "누설하는"것으로 간주 할 수 있습니다. 간단히 말해서 그것을 생성하고 결코 릴리스되지 않기 때문입니다.하지만 한 번만 생성되므로 괜찮습니다.

은 프로그램을 실행하고 누수 탐지를하고, 다음 디버거에서 깨고

포 0x4b2720 (누출 된 객체의 주소로 대체)

실제로 누수되는 것을 문자열 볼을 사용해보십시오.

특히 캐싱 된 항목이 있으면 누수가 오 탐지 될 수 있습니다.

+0

+1 디버깅 방법. – Abizern

+0

이것은 po가 작동하지 않습니다 0x4b2720 (유출 된 개체의 주소로 대체하십시오) gdb는 아무것도 인쇄하지 않습니다 ... –

1

-1/2

@""가 누출 [[[NSString alloc] init] autorelease]; [[NSString alloc] init] 동일하다.

규칙을 기억하십시오 : init/retainautorelease/release과 균형을 유지해야합니다.

관련 문제