iPhone应用程序内存泄漏

发布于 2024-11-26 23:41:46 字数 3037 浏览 0 评论 0原文

嗨,大家好!我是 iPhone 开发新手。我遇到内存泄漏问题。我有这样的代码。

do {

    int s = sqlite3_step(statement);
    switch (s) {
        case SQLITE_ROW:{

            Article *a = [[[Article alloc] init] autorelease];
            for (int i = 0; i < columnCount; i++) {
                const char *columnName = sqlite3_column_name(statement, i);
                if(strncmp(columnName, "title", strlen("title")) == 0){
                    const char* colStr = (char*)sqlite3_column_text(statement, i);
                    if(colStr != NULL)
                        a.title = [[[NSString alloc] initWithCString: colStr encoding:NSUTF8StringEncoding] autorelease];
                    continue;
                }
                if(strncmp(columnName, "author", strlen("author")) == 0){
                    const char* colStr = (char*)sqlite3_column_text(statement, i);
                    if(colStr != NULL)
                        a.author = [[[NSString alloc] initWithCString:colStr encoding:NSUTF8StringEncoding] autorelease];
                    continue;
                }
                if(strncmp(columnName, "description", strlen("description")) == 0){
                    const char* colStr = (char*)sqlite3_column_text(statement, i);
                    if(colStr != NULL)
                        a.description = [[[NSString alloc] initWithCString:colStr encoding:NSUTF8StringEncoding] autorelease];
                    continue;
                }
                if(strncmp(columnName, "link", strlen("link")) == 0){
                    const char* colStr = (char*)sqlite3_column_text(statement, i);
                    if (colStr) 
                        a.link = [[[NSString alloc] initWithCString:colStr encoding:NSUTF8StringEncoding] autorelease];
                    continue;
                }
                if(strncmp(columnName, "imageUrl", strlen("imageUrl")) == 0){
                    const char* colStr = (char*)sqlite3_column_text(statement, i);
                    if (colStr)
                        a.imageUrl = [[[NSString alloc] initWithCString:colStr encoding:NSUTF8StringEncoding] autorelease];
                    continue;
                }
                if(strncmp(columnName, "pubDate", strlen("pubDate")) == 0){
                    const char* colStr = (char*)sqlite3_column_text(statement, i);
                    if(colStr)
                        a.pubDate = [[[NSString alloc] initWithCString:colStr encoding:NSUTF8StringEncoding] autorelease];
                    continue;
                }
            }
            [array insertObject:a atIndex:0];
        }
        break;
        case SQLITE_DONE:
            sqlite3_finalize(statement);
            dataForReadingAvailable = NO;
            break;
        default:{
            NSLog(@"getArticlesForFeed:sqlite3_step failed.Error:%s",sqlErrMsg);
            return nil;
        }
        break;
    }   
}while(dataForReadingAvailable);

Xcode 中的工具显示,当我分配对象以及初始化它的属性时,我会发生内存泄漏。但为什么会发生这种情况。所有对象都是自动释放的,所以我认为不会是这种情况。 谢谢。

Hi, guys! i'm newbie in iphone development. I have problems with the memory leak. I have such code.

do {

    int s = sqlite3_step(statement);
    switch (s) {
        case SQLITE_ROW:{

            Article *a = [[[Article alloc] init] autorelease];
            for (int i = 0; i < columnCount; i++) {
                const char *columnName = sqlite3_column_name(statement, i);
                if(strncmp(columnName, "title", strlen("title")) == 0){
                    const char* colStr = (char*)sqlite3_column_text(statement, i);
                    if(colStr != NULL)
                        a.title = [[[NSString alloc] initWithCString: colStr encoding:NSUTF8StringEncoding] autorelease];
                    continue;
                }
                if(strncmp(columnName, "author", strlen("author")) == 0){
                    const char* colStr = (char*)sqlite3_column_text(statement, i);
                    if(colStr != NULL)
                        a.author = [[[NSString alloc] initWithCString:colStr encoding:NSUTF8StringEncoding] autorelease];
                    continue;
                }
                if(strncmp(columnName, "description", strlen("description")) == 0){
                    const char* colStr = (char*)sqlite3_column_text(statement, i);
                    if(colStr != NULL)
                        a.description = [[[NSString alloc] initWithCString:colStr encoding:NSUTF8StringEncoding] autorelease];
                    continue;
                }
                if(strncmp(columnName, "link", strlen("link")) == 0){
                    const char* colStr = (char*)sqlite3_column_text(statement, i);
                    if (colStr) 
                        a.link = [[[NSString alloc] initWithCString:colStr encoding:NSUTF8StringEncoding] autorelease];
                    continue;
                }
                if(strncmp(columnName, "imageUrl", strlen("imageUrl")) == 0){
                    const char* colStr = (char*)sqlite3_column_text(statement, i);
                    if (colStr)
                        a.imageUrl = [[[NSString alloc] initWithCString:colStr encoding:NSUTF8StringEncoding] autorelease];
                    continue;
                }
                if(strncmp(columnName, "pubDate", strlen("pubDate")) == 0){
                    const char* colStr = (char*)sqlite3_column_text(statement, i);
                    if(colStr)
                        a.pubDate = [[[NSString alloc] initWithCString:colStr encoding:NSUTF8StringEncoding] autorelease];
                    continue;
                }
            }
            [array insertObject:a atIndex:0];
        }
        break;
        case SQLITE_DONE:
            sqlite3_finalize(statement);
            dataForReadingAvailable = NO;
            break;
        default:{
            NSLog(@"getArticlesForFeed:sqlite3_step failed.Error:%s",sqlErrMsg);
            return nil;
        }
        break;
    }   
}while(dataForReadingAvailable);

Tools from Xcode shows that i have leak memory when i a'm allocated object and when i initialized it properties. But why it's happens. All objects is autorealeased, so i think that will not to be such situation.
Thanks.

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

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

发布评论

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

评论(1

甲如呢乙后呢 2024-12-03 23:41:46

我想也许你在某个地方用新指针覆盖了分配的内存。

我会替换

Article *a = [[[Article alloc] init] autorelease];

Article *a = [[Article alloc] init];
//some code
[a release]; //when you don't need it anymore

This is not a Good Practice to use autorelease much。顺便说一句,如果有很多对象,它甚至可能会减慢您的应用程序的速度。
像我这样的字符串

 a.title = [[[NSString alloc] initWithCString: colStr encoding:NSUTF8StringEncoding] autorelease];

将替换为

 a.title = [NSString stringWithCString:colStr encoding:NSUTF8StringEncoding];

在这种情况下,您还依赖于自动释放池,但它要简单得多。

编辑:
事实上,您的“文章”分配位于 do-while 循环中。
在字符串 [array insertObject:a atIndex:0]; 中,你的数组保留了对象,你不再需要它了,但你依赖于自动释放。分析器(或您正在使用的工具)看到,您将分配放置在循环的主体中,而没有在每次迭代后释放它。这样,在循环的第二次迭代中,您将覆盖“a”对象,从而丢失旧指针并以这种方式泄漏内存(池不会找到该指针,因为“a”被覆盖)。即使您只通过一次循环,分析器也不会关心并给您一个警告。

I think perhaps you overwrite the allocated memory with the new pointer somewhere.

I would replace

Article *a = [[[Article alloc] init] autorelease];

with

Article *a = [[Article alloc] init];
//some code
[a release]; //when you don't need it anymore

This is not a good practice to use autorelease much. It can even slow down your app btw in case of many objects.
And the strings like

 a.title = [[[NSString alloc] initWithCString: colStr encoding:NSUTF8StringEncoding] autorelease];

I would replace with

 a.title = [NSString stringWithCString:colStr encoding:NSUTF8StringEncoding];

In this case you also rely on autorelease pool, but it's much simpler.

EDIT:
Indeed, your 'Article' allocation is in the do-while loop.
In string [array insertObject:a atIndex:0]; your aray retains object and you don't need it anymore, but you rely on autorelease. Analyzer (or what tool you're using) sees, that you placed allocation in the cycle's body without releasing it after each iteration. This way, on the second iteration of the loop, you overwrite your "a" object, loosing the old pointer and leaking memory this way (pool won't find this pointer, since "a" overwritten). Even if you pass your loop only once, the analyzer does not care and gives you a warning.

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