内存泄漏在iPhone应用程序中

时间:2011-07-29 11:43:52

标签: iphone objective-c memory-leaks

嗨,伙计们!我是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的工具显示,当我分配了对象并初始化它时,我有泄漏内存。但为什么会发生这种情况。所有对象都是自动解决的,所以我认为不会出现这种情况。 感谢。

1 个答案:

答案 0 :(得分:0)

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

我会替换

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

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

使用autorelease不是一个好习惯。它可以在很多物体的情况下减慢你的应用程序btw。 和

这样的字符串
 a.title = [[[NSString alloc] initWithCString: colStr encoding:NSUTF8StringEncoding] autorelease];

我会替换为

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

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

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