Утечки при добавлении в массив в цикле while - PullRequest
1 голос
/ 27 апреля 2011

У меня есть функция с именем: - (void) AddSortedCustomFeed :(NSMutableArray*) rssList; эта функция добавляет элементы (Статьи) из базы данных sqlite в NSMutableArray вот как эта функция работает:

- (void) AddSortedCustomFeed :(NSMutableArray*)rssList {    
    NSLog(@"\n\n\n ----- Add Sorted SQL Database -----");
    NSLog(@"Start");
    // Create Query String.
    NSString* sqliteQuery = [NSString stringWithFormat:@"SELECT mainLink, title, summary, pubDate, author, imageLink, body, favorites, pubdatetime FROM ARTICLES WHERE customfeed  = 'Y' ORDER BY pubdatetime DESC"];
    NSLog(@"Query String is: %@", sqliteQuery);
    // Pointer to Article and Statement.
    Article* article;
    sqlite3_stmt* statement;

    // Prepare SQL for work.
    if( sqlite3_prepare_v2(articlesDB, [sqliteQuery UTF8String], -1, &statement, NULL) == SQLITE_OK ) {
        // Get next row from database.
        while( sqlite3_step(statement) == SQLITE_ROW ) {
            // Alloc and init article.

            article = [[Article alloc] initWithValues:[NSString stringWithUTF8String:(const char*)sqlite3_column_text(statement, 1)] 
                                             mainLink:[NSString stringWithUTF8String:(const char*)sqlite3_column_text(statement, 0)] 
                                              summary:[NSString stringWithUTF8String:(const char*)sqlite3_column_text(statement, 2)] 
                                              pubDate:[NSString stringWithUTF8String:(const char*)sqlite3_column_text(statement, 3)] 
                                               author:[NSString stringWithUTF8String:(const char*)sqlite3_column_text(statement, 4)] 
                                            imageLink:[NSString stringWithUTF8String:(const char*)sqlite3_column_text(statement, 5)] ];


            //article.body      = [NSString stringWithUTF8String:(const char*)sqlite3_column_text(statement, 6)];
            NSString* favo    = [NSString stringWithUTF8String:(const char*)sqlite3_column_text(statement, 7)];
            article.favorite  = [favo hasPrefix:@"N"] ? NO : YES; 

            // Add to list.
            [rssList addObject:article];
            // Release article.
            [article release];
        }
    }
    else NSLog( @"SortSQLDatabase: Failed from sqlite3_prepare_v2. Error is:  %s", sqlite3_errmsg(articlesDB) );

    // Finalize and close database.
    sqlite3_finalize(statement);

    NSLog(@"End\n\n\n");
}

Как вы можете видеть в этой функции я создаю статьюArticle* article; и в то время как цикл размещает и инициализирует его.После этого я добавляю объект Article в NSMutableArray и затем освобождаю его, но затем я вызываю [article release];, ведь ведь она должна вызывать функцию delloc, которую она не вызывает?Я не могу понять почему.Я пытаюсь разными способами, но все мои попытки терпят неудачу.Это статья о Статья Класс - ссылка

Ответы [ 2 ]

2 голосов
/ 27 апреля 2011

dealloc не вызывается для объекта Article, потому что [rssList addObject:article] сохраняет объект article.Таким образом, ваш счет удержания равен 1, и он не будет выпущен.Теперь, если вы освободите rssList (или удалите объект article из массива), счетчик сохранений достигнет 0, и объект будет освобожден.

PS: если у вас есть цикл while, подобный этому, я рекомендую добавитьпул авто-релизов, чтобы избежать создания объектов авто-релизов.

while( .. )
{
  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  // .. your code .. //
  [pool release];
}

PPS: если вы нажмете 'Shift + Cmd + A', XCode статически проанализирует ваш код и обнаружит утечки / ошибки памяти,У меня есть ощущение, что он найдет его.

0 голосов
/ 27 апреля 2011

У вас есть несколько вариантов, вы должны поэкспериментировать, чтобы увидеть, что вы хотите сделать.По сути, после того, как вы отправили [article release];, вам нужно начать с самого начала, чтобы сделать article.Таким образом, вы можете сделать что-то вроде

Article *article = [[Article alloc] initWithValues:[NSString stringWithUTF8String:(const char*)sqlite3_column_text(statement, 1)] 
                                         mainLink:[NSString stringWithUTF8String:(const char*)sqlite3_column_text(statement, 0)] 
                                          summary:[NSString stringWithUTF8String:(const char*)sqlite3_column_text(statement, 2)] 
                                          pubDate:[NSString stringWithUTF8String:(const char*)sqlite3_column_text(statement, 3)] 
                                           author:[NSString stringWithUTF8String:(const char*)sqlite3_column_text(statement, 4)] 
                                        imageLink:[NSString stringWithUTF8String:(const char*)sqlite3_column_text(statement, 5)] ];

и оставить [article release]; там, где оно сейчас.Убедитесь, что вынесли линию Article* article; сверху.Это, вероятно, много накладных расходов, которые вы не хотите.

Вы можете оставить все как есть и переместить [article release]; вниз так, чтобы это было за пределами цикла.

...