在while循环中添加数组时泄漏

时间:2011-04-27 12:43:31

标签: iphone loops memory-leaks while-loop iso

我有一个名为- (void) AddSortedCustomFeed :(NSMutableArray*) rssList;的函数,这个函数将sqlite数据库中的项目(Articles)添加到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;并在while循环中分配并初始化它。之后我将Article对象添加到NSMutableArray然后释放它,但是然后我调用[article release];女巫必须调用它没有调用的delloc函数?我不明白为什么。我尝试了不同的方法,但我的所有尝试都崩溃了。这是关于文章类 - link

的文章

2 个答案:

答案 0 :(得分:2)

未在Article对象上调用dealloc,因为[rssList addObject:article] 保留文章对象。因此,您的保留计数为1,并且不会被释放。现在,如果您释放rssList(或从数组中删除article对象),则保留计数将为0,并且将释放该对象。

P.S:如果你有这样的while循环,我建议你添加一个自动释放池,以避免自动释放对象的建立。

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

P.P.S:如果你点击'Shift + Cmd + A'XCode会statically analyze你的代码,并寻找泄漏/内存不幸。我觉得它会找到一些。

答案 1 :(得分:0)

您有几个选择,您应该尝试看看您想要做什么。基本上,一旦您发送[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];,这样就可以在循环之外了。