2010-04-20 4 views
0

Dans mon application, un lecteur RSS, je reçois des fuites de mémoire que je ne peux pas réparer parce que je ne comprends pas d'où ils viennent. Voici le code signalé par Instruments.iPhone - méthode de lecture de base de données et les fuites de mémoire

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

`

J'ai beaucoup de "article" et NSString fuite correspondant à ces utilisant:

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

J'ai essayé beaucoup de code différent, je l'ai toujours ces fuites. Quelqu'un a une idée pour m'aider?

Répondre

1

Vous sont des articles qui fuient parce que:

article = nil; 
[article release]; 

Pourquoi essayez-vous de libérer nul?

Supprimez simplement l'article de réglage de ligne à zéro, il n'est pas nécessaire. Étant donné l'échantillon ci-dessus, il y a probablement beaucoup plus de problèmes dans ce code.

+0

Nous vous remercions de votre réponse. J'ai essayé d'ajouter cela parce que je travaille sur ce point depuis longtemps maintenant et je suis à la recherche de cela. Comme vous l'avez dit le problème ne vient pas de ce point (qui ne change rien (avec ou sans) selon les Instruments). Vous avez dit qu'il y a beaucoup plus de problèmes dans ce code, avez-vous une idée de la raison pour laquelle ces lignes créent des fuites: NSString * aName = [NSString stringWithUTF8String: (char *) sqlite3_column_text (compiledStatement, 1)]; Nous vous remercions de votre temps et de votre aide. – Do8821

+0

Supprimer l'affectation à zéro arrêtera vos articles qui fuient. –

+0

Vous faites également une fuite sur le tableau "articles", et vous devriez le publier à la fin de la méthode. Si vous souhaitez le conserver en tant que variable d'instance, vous devez utiliser une attribution de propriété. –

0

J'ai finalement trouvé une partie de la solution par moi-même. Mon erreur était d'initialiser le tableau "articles" INTO ma fonction. En effet, chaque fois que j'ai appelé ma fonction, j'ai perdu les données précédentes dans ce tableau. Maintenant, j'initialiser le tableau « articles » lors du lancement et je simplement supprimer son contenu dans ma fonction que:

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

Puis

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

Maintenant, je dois me concentrer sur les fuites « article » causées par [articles removeAllObjects]. Si je ne retire pas tous les objets, je n'ai pas de fuites mais si je le fais, j'ai des fuites. Une idée? Comment pourrais-je vider mon tableau sans fuir ces objets article?

+0

lorsque vous dites "NSString * aName = [NSString stringWithUTF8String: (char *) sqlite3_column_text (compiledStatement, 1)];", aName doit être libéré.Sinon, il va jeter la fuite de mémoire. – Satyam

1

Je viens de passer les derniers jours en dépistant cela et ci-dessous résolu le problème pour moi.

Ajout d'une méthode dealloc à vos articles NSObject et libération de toutes les chaînes. Ensuite, dans votre méthode readArticlesFromDatabase, publiez d'abord les articles, puis faites votre init.