2013-05-24 2 views
0

다음 코드에서 장비가 메모리 누수를 나타냅니다. 나는 모든 곳에서 유지 된 수를 유지하도록 확실히했다. 나는 또한 autorelease 수영장을 추가했습니다, 아직도 메모리 누수가 있습니다. 어떻게 해결할 수 있을까요?SKDatabase 함수에서 메모리 누수를 해결하는 방법은 무엇입니까?

코드 블록 :

- (NSArray *)lookupAllForSQL:(NSString *)sql 
{ 
    sqlite3_stmt *statement; 
    id result = nil; 
    NSMutableArray *thisArray = [NSMutableArray arrayWithCapacity:4]; 
    statement = [self prepare:sql]; 
    if (statement) 
    { 
     while (sqlite3_step(statement) == SQLITE_ROW) 
     { 
      NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

      NSMutableDictionary *thisDict = [NSMutableDictionary dictionaryWithCapacity:4]; 
      for (int i = 0 ; i < sqlite3_column_count(statement) ; i++) 
      { 
       NSAutoreleasePool *poolInside = [[NSAutoreleasePool alloc] init]; 
       if(sqlite3_column_type(statement,i) == SQLITE_NULL) 
       { 
        continue; 
       } 
       if (sqlite3_column_decltype(statement,i) != NULL && 
        strcasecmp(sqlite3_column_decltype(statement,i),"Boolean") == 0) 
       { 
        result = [NSNumber numberWithBool:(BOOL)sqlite3_column_int(statement,i)]; 
       } 
       else if (sqlite3_column_type(statement,i) == SQLITE_INTEGER) 
       { 
        result = [NSNumber numberWithInt:(int)sqlite3_column_int(statement,i)]; 
       } 
       else if (sqlite3_column_type(statement,i) == SQLITE_FLOAT) 
       { 
        result = [NSNumber numberWithFloat:(float)sqlite3_column_double(statement,i)]; 
       } 
       else 
       { 
        if((char *)sqlite3_column_text(statement,i) != NULL) 
        { 
         //result = [NSString stringWithUTF8String:(char *)sqlite3_column_text(statement,i)]; 
         [thisDict setObject:[NSString stringWithUTF8String:(char *)sqlite3_column_text(statement,i)] 
            forKey:[NSString stringWithUTF8String:sqlite3_column_name(statement,i)]]; 
         //[result release]; 
         result = nil; 
        } 
       } 
       if (result) 
       { 
        [thisDict setObject:result forKey:[NSString stringWithUTF8String:sqlite3_column_name(statement,i)]]; 
       } 
       [poolInside drain]; 
      } 
      [thisArray addObject:[NSDictionary dictionaryWithDictionary:thisDict]]; 
      [pool drain]; 
     } 
    } 
    sqlite3_finalize(statement); 
    return thisArray; 
} 

악기 스크린 샷 :

enter image description here

+1

가끔 SQLite가 실수로'free()'해야하는 문자열을 반환합니다. 그것이 문제인지보십시오. – CodaFi

+0

@CodaFi 당신이 맞는 것 같습니다. 이 함수 내에서 변수가 아니라 적절하게 처리해야하는 변수를 반환하십시오. 감사합니다 –

+0

그 남자의 레포에 문제를 던질 수도 있습니다. – CodaFi

답변

0

나는 해결책을 얻었다. 이 함수는 제대로 릴리스하지 않은 NSArray를 반환했습니다. 따라서 모든 변수가이 함수가 아니라 메모리 누수를 일으켰습니다.

This video 나를 이해하는 데 도움이되었습니다.

0

나는 continue 문이 문제가 될 수 있다고 생각합니다. 문은 제어가 가장 가까운 루프의 다음 인터 레이션으로 넘어 가게하므로 조건 (sqlite3_column_type(statement,i) == SQLITE_NULL)true 인 경우 컨트롤은 다음 반복으로 전달되고 'poolInside'풀이 비워지지 않습니다. 따라서 다음을 사용합니다 :

if(sqlite3_column_type(statement,i) == SQLITE_NULL) 
{ 
    [poolInside drain]; 
    continue; 
} 

그러나 이것은 누출 문제를 해결하기 위해 추가 한 오류 일 수 있으므로 @CodaFi의 설명은 여전히 ​​유효합니다.

[thisArray addObject:[NSDictionary dictionaryWithDictionary:thisDict]]; 

모든 poolInsideNSDictionary을 누출 : 모두가 poolInside 누출의 결과를 살펴 경우 완전성을 위해서

, 당신은이 줄을 볼 수 있습니다 새는 곳. 따라서 반환 된 배열에는 누출 된 객체가 포함됩니다. 또한 중첩 된 NSAutoreleasePool을 유출하면 for 루프 내부에서 생성 된 객체가 유출 될 수도 있습니다. 당신이 게시 한 "Instruments Screenshot"는 그 행동을 보여줍니다.

관련 문제