iPhone - метод чтения базы данных и утечки памяти - PullRequest
0 голосов
/ 20 апреля 2010

в моем приложении для чтения RSS я получаю утечки памяти, которые не могу исправить, потому что не могу понять, откуда они берутся. Вот код, указанный инструментами.

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

`

У меня много утечек "Article" и соответствие NSString этим, используя:

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

Я пробовал много разных кодов, у меня всегда есть эти утечки. У кого-нибудь есть идея, чтобы помочь мне?

Ответы [ 3 ]

1 голос
/ 09 июня 2010

Я только что провел последние несколько дней, выслеживая это, и ниже решил проблему для меня.

Добавление метода dealloc в ваши статьи NSObject и освобождение всех строк. Затем в вашем методе readArticlesFromDatabase сначала выпускайте статьи, а затем выполняйте инициализацию.

1 голос
/ 20 апреля 2010

Вы пропускаете статьи, потому что:

article = nil;
[article release];

Почему вы пытаетесь выпустить ноль?

Просто удалите статью с настройкой строки в ноль, она не нужна.Учитывая приведенный выше пример, в этом коде, вероятно, гораздо больше проблем.

0 голосов
/ 26 апреля 2010

Я наконец нашел часть решения самостоятельно.

Моя ошибка состояла в том, чтобы инициализировать массив «article» INTO моей функции. Действительно, каждый раз, когда я вызывал свою функцию, я терял предыдущие данные в этом массиве. Теперь я инициализирую массив «article» во время запуска и просто удаляю его содержимое в своей функции следующим образом:

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

Теперь я должен сосредоточиться на утечках «Article», вызванных [article removeAllObjects]. Если я не удаляю все объекты, у меня нет никаких утечек, но если я делаю, у меня есть утечки. Любая идея? Как я мог очистить свой массив, не пропуская эти объекты Article?

...