2010-04-20 6 views
0

내 응용 프로그램, RSS 판독기에서 그들이 어디서 왔는지 이해할 수 없기 때문에 수정할 수없는 메모리 누수가 발생합니다. 다음은 Instruments에서 지적한 코드입니다. iPhone - 데이터베이스 읽기 방법 및 메모리 누수

`

-(void) readArticlesFromDatabase { 



[self setDatabaseInfo]; 

sqlite3 *database; 

articles = [[NSMutableArray alloc] init]; 

if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) { 
    const char *sqlStatement = "select * from articles"; 
    if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) { 
    while(sqlite3_step(compiledStatement) == SQLITE_ROW) { 

    NSString *aName = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)]; 
    NSString *aDate = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 2)]; 
    NSString *aUrl = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 3)]; 
    NSString *aCategory = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 4)]; 
    NSString *aAuthor = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 5)]; 
    NSString *aSummary = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 6)]; 
    NSMutableString *aContent = [NSMutableString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 7)]; 
    NSString *aNbrComments = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 8)]; 
    NSString *aCommentsLink = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 9)]; 
    NSString *aPermalink = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 11)]; 

    [aContent replaceCharactersInRange: [aContent rangeOfString: @"http://www.mywebsite.com/img/action-on.gif"] withString: @"hellocoton-action-on.gif"]; 
    [aContent replaceCharactersInRange: [aContent rangeOfString: @"hhttp://www.mywebsite.com/img/action-on-h.gif"] withString: @"hellocoton-action-on-h.gif"]; 
    [aContent replaceCharactersInRange: [aContent rangeOfString: @"hthttp://www.mywebsite.com/img/hellocoton.gif"] withString: @"hellocoton-hellocoton.gif"]; 

    NSString *imageURLBrut = [self parseArticleForImages:aContent];  
    NSString *imageURLCache = [imageURLBrut stringByReplacingOccurrencesOfString:@":" withString:@"_"]; 
    imageURLCache = [imageURLCache stringByReplacingOccurrencesOfString:@"/" withString:@"_"]; 
    imageURLCache = [imageURLCache stringByReplacingOccurrencesOfString:@" " withString:@"_"]; 

    NSString *uniquePath = [tmp stringByAppendingPathComponent: imageURLCache]; 
    if([[NSFileManager defaultManager] fileExistsAtPath: uniquePath]) { 
    imageURLCache = [@"../tmp/" stringByAppendingString: imageURLCache]; 
    [aContent replaceCharactersInRange: [aContent rangeOfString: imageURLBrut ] withString: imageURLCache]; 
    } 

    Article *article = [[Article alloc] initWithName:aName date:aDate url:aUrl category:aCategory author:aAuthor summary:aSummary content:aContent commentsNbr:aNbrComments commentsLink:aCommentsLink commentsRSS:@"" enclosure:aPermalink enclosure2:@"" enclosure3:@""]; 

    [articles addObject:article]; 

    article = nil; 
    [article release]; 
    } 
    } 
    sqlite3_finalize(compiledStatement); 

} 
sqlite3_close(database); 
} 

내가 "조"의 여지가 유출하고있는 NSString이 사용하여 일치 :

[NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, X)]; 

나는 항상이 누수가 다른 코드를 많이 했어요. 누구든지 날 도울 생각이있어?

답변

1

당신 누출되는 기사 이유는

article = nil; 
[article release]; 

가 왜 전무를 해제하려고?

라인 설정 아티클을 nil로 제거하면 필요하지 않습니다. 위의 샘플을 감안할 때, 아마 그 코드에 더 많은 문제가있을 것입니다.

+0

답장을 보내 주셔서 감사합니다. 나는 오랫동안 그 지점에서 일하고 있기 때문에 나는 이것을 추가하려고 노력했다. 당신이 말했듯이 문제는 그 시점에서 나온 것이 아닙니다. (악기에 따라 달라 지든 없든간에). 당신은 그 코드에 더 많은 문제가 있다고 말했고,이 라인들이 누수를 만드는 이유에 대해 생각해 보셨습니까? NSString * aName = [NSString stringWithUTF8String : (char *) sqlite3_column_text (compiledStatement, 1)]; 시간과 도움에 감사드립니다. – Do8821

+0

지정을 없애면 누설 된 기사가 중지됩니다. –

+0

또한 배열 "articles"이 누출되어 메서드 끝 부분에서이를 해제해야합니다. 인스턴스 변수로 유지하려면 속성 할당을 사용해야합니다. –

0

마지막으로 솔루션의 일부가 나 혼자 발견되었습니다.

내 실수는 "기사"배열을 내 함수로 초기화하는 것이 었습니다. 실제로 필자가 함수를 호출 할 때마다이 배열에서 이전 데이터를 잃어 버렸습니다. 은 이제 시작하는 동안 "기사"배열을 초기화하고 나는 단순히 나의 기능에 자사의 콘텐츠를 제거 : 다음

- (void)applicationDidFinishLaunching:(UIApplication *)application { 
     // My Code 
     articles = [[NSMutableArray alloc] init]; 
     // My Code 
} 

-(void) readArticlesFromDatabase { 

    [self setDatabaseInfo]; 
    sqlite3 *database; 

    [articles removeAllObjects]; 

    if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) { 
     const char *sqlStatement = "select * from articles"; 
     sqlite3_stmt *compiledStatement; 
     if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) { 
      while(sqlite3_step(compiledStatement) == SQLITE_ROW) { 

       NSString *aName = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)]; 
       NSString *aDate = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 2)]; 
       NSString *aUrl = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 3)]; 
       NSString *aCategory = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 4)]; 
       NSString *aAuthor = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 5)]; 
       NSString *aSummary = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 6)]; 
       NSMutableString *aContent = [NSMutableString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 7)]; 
       NSString *aNbrComments = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 8)]; 
       NSString *aCommentsLink = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 9)]; 
       NSString *aPermalink = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 11)]; 

       [aContent stringByReplacingOccurrencesOfString: @"http://www.mywebsite.com/img/action-on.gif" withString: @"hellocoton-action-on.gif"]; 
       [aContent stringByReplacingOccurrencesOfString: @"http://www.mywebsite.com/img/action-on-h.gif" withString: @"hellocoton-action-on-h.gif"]; 
       [aContent stringByReplacingOccurrencesOfString: @"http://www.mywebsite.com/img/hellocoton.gif" withString: @"hellocoton-hellocoton.gif"]; 

       NSString *imageURLBrut = [self parseArticleForImages:aContent]; 
       NSString *imageURLCache = [imageURLBrut stringByReplacingOccurrencesOfString:@":" withString:@"_"]; 
       [imageURLCache stringByReplacingOccurrencesOfString:@"/" withString:@"_"]; 
       [imageURLCache stringByReplacingOccurrencesOfString:@" " withString:@"_"]; 

       NSString *uniquePath = [tmp stringByAppendingPathComponent: imageURLCache]; 
       if([[NSFileManager defaultManager] fileExistsAtPath: uniquePath]) { 
        imageURLCache = [@"../tmp/" stringByAppendingString: imageURLCache]; 
        [aContent replaceCharactersInRange: [aContent rangeOfString: imageURLBrut ] withString: imageURLCache]; 
       } 

       Article *article = [[Article alloc] initWithName:aName date:aDate url:aUrl category:aCategory author:aAuthor summary:aSummary content:aContent commentsNbr:aNbrComments commentsLink:aCommentsLink commentsRSS:@"" enclosure:aPermalink enclosure2:@"" enclosure3:@""]; 

       [articles addObject:article]; 

       [article release]; 
      } 
     } 
     sqlite3_finalize(compiledStatement); 
    } 
    sqlite3_close(database); 
} 

지금은 발생하는 "제"누수에 집중해야 [articles removeAllObjects] 의해. 개체를 모두 지우지 않으면 누출이 발생하지 않지만 누출 된 경우 누출이 발생합니다. 어떤 생각? 어떻게이 기사 객체를 유출하지 않고 배열을 비울 수 있습니까?

+0

"NSString * aName = [NSString stringWithUTF8String : (char *) sqlite3_column_text (compiledStatement, 1)];"라고 말하면 aName이 릴리스되어야합니다.그렇지 않으면 메모리 누수가 발생합니다. – Satyam

1

방금 ​​지난 며칠 동안이 문제를 추적하면서 저를 위해 문제를 해결했습니다.

기사 NSObject에 dealloc 메소드를 추가하고 모든 문자열을 해제하십시오. 그런 다음 readArticlesFromDatabase 메소드에서 먼저 기사를 릴리스 한 다음 init을 수행하십시오.