开发者

iPhone - database reading method and memory leaks

开发者 https://www.devze.com 2022-12-27 18:28 出处:网络
in my application, a RSS r开发者_如何转开发eader, I get memory leaks that I can\'t fix because I can\'t understand from where they come from. Here is the code pointed out by Instruments.

in my application, a RSS r开发者_如何转开发eader, I get memory leaks that I can't fix because I can't understand from where they come from. Here is the code pointed out by Instruments.

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

`

I have a lot of "Article" leaked and NSString matching with these using :

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

I tried a lot of different code I always have these leaks. Anyone has got an idea to help me?


You are leaking articles because:

article = nil;
[article release];

Why are you attempting to release nil?

Just remove the line setting article to nil, it is not needed. Given the above sample, there are probably a lot more problems in that code.


I just spent the last few days tracking this down and below resolved the issue for me.

Adding a dealloc method to your articles NSObject and release all strings. Then in your readArticlesFromDatabase method first release articles and then do your init.


I finally found a part of the solution by myself.

My mistake was to initialize the "articles" array INTO my function. Indeed, each time I called my function, I lost the previous data in this array. Now I initialize the "articles" array during launching and I simply remove its content in my function as that :

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

Then

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

Now I have to focus on the "Article" leaks caused by [articles removeAllObjects]. If I don't remove all objects I don't have any leaks but if I do, I have got leaks. Any idea? How could I empty my array without leaking these Article Objects?

0

精彩评论

暂无评论...
验证码 换一张
取 消