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

发布于 2024-11-03 11:27:38 字数 2798 浏览 2 评论 0原文

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

I have function named: - (void) AddSortedCustomFeed :(NSMutableArray*) rssList; this function adds items(Articles) from sqlite database to NSMutableArray here how this function works:

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

How you can see in this function I create article Article* article; and in while loop alloc and initialize it. After that I add Article object to NSMutableArray and then release it, but then I call [article release]; witch must call delloc function it doesn't calls ? I cant understand why. I try different ways but all my tries crashes. This is article about Article Class - link

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

溺深海 2024-11-10 11:27:38

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

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

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

PPS:如果您按“Shift+Cmd+A”,XCode 将 静态分析您的代码并查找泄漏/内存事故。我有预感它会找到一些。

dealloc isn't called on the Article object because [rssList addObject:article] retains the article object. So your retain count is 1, and it won't be released. Now if you release rssList (or remove the article object from the array), the retain count will hit 0, and the object will be released.

P.S: if you have a while loop like this I recommend you add an autorelease pool to avoid autorelease objects build up.

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

P.P.S: if you hit 'Shift+Cmd+A' XCode will statically analyze your code and look for leaks/memory mishaps. I have a feeling it will find some.

娇纵 2024-11-10 11:27:38

你有几个选择,你应该尝试看看你想做什么。基本上,一旦您发送了[文章发布];,您将需要从头开始制作文章。因此,您可以执行类似的操作

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]; 向下移动,以便将其移到循环之外。

You have a few choices, you should experiment to see what you want to do. Basically, once you have sent [article release]; you will need to start from the beginning to make the article. So you could do something like

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)] ];

and leave [article release]; where it is now. Be sure to take out your line of Article* article; from above though. This is probably lots of overhead that you don't want.

You could keep everything the same and move [article release]; down so that is it outside of the loop.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文