内存管理存在问题?

时间:2010-09-17 12:17:26

标签: objective-c ipad

我正在开发一个应用程序,在其中我使用数据库操作。我在数据库类中编写的方法如下。

-(NSMutableArray *)getData: (NSString *)dbPath{
    NSMutableArray *dataArray = [[NSMutableArray alloc] init];

    if(sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK){
        NSString *sqlQuery = [NSString stringWithFormat:@"SELECT empID, addText FROM Employee WHERE nameID = %@", nameID];
        sqlite3_stmt *selectstmt;
        if(sqlite3_prepare_v2(database, [sqlQuery UTF8String], -1, &selectstmt, NULL) == SQLITE_OK){

           while (sqlite3_step(selectstmt) == SQLITE_ROW){
                [dataArray addObject:[[NSMutableDictionary alloc] init]];

                [[dataArray lastObject] setObject:[NSString 
                                 stringWithFormat:@"%d", sqlite3_column_int(selectstmt, 0)] forKey:@"empID"];

                [[dataArray lastObject] setObject:[NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt,1)] forKey:@"addText"];
            }
        }

        sqlite3_finalize(selectstmt);
    }
    sqlite3_close(database);
    return dataArray;
}

上面的代码在模拟器上运行正常,但不能在设备上运行。 我也在跟踪内存泄漏,其中我在上面的方法代码中创建了内存泄漏。但我无法解决内存泄漏问题。

现在我也发现了以下方法中的内存泄漏。

  • (id)initWithString:(NSString *)str attributes:(NSDictionary *)attributes

{     if((self = [super init])) {         _buffer = [str mutableCopy];         _attributes = [NSMutableArray arrayWithObjects:[ZAttributeRun attributeRunWithIndex:0 attributes:attributes],nil]; }     回归自我; }

_buffer附近的泄漏= [str mutableCopy];。并且泄漏跟踪使我在输出中连续增加NSCFString字符串分配。我怎么维持它?

提前致谢。

4 个答案:

答案 0 :(得分:2)

您的泄漏是您不释放dataArray对象,也不释放您在while循环中创建的可变词典。考虑自动释放可变数组,并在将它们添加到数组后手动释放字典。

至于为什么它在设备上“不起作用”,你需要更具体地了解发生什么以及为什么这不是你所期望的。

答案 1 :(得分:1)

从第一眼看,你有两个可以泄漏的地方:

NSMutableArray *dataArray = [[NSMutableArray alloc] init];
...
return dataArray;

调用者方法负责释放从您的方法返回的数组 - 检查它是否。

此外,您的方法名称与obj-c指南不一致 - 他们建议返回非自动释放对象的方法(因此调用者负责释放它们)应该在其名称中包含create,alloc,copy。因此,最好从此方法返回自动释放的数组(return [dataArray autorelease];,让调用者决定是否需要保留数组。

第二名是

[dataArray addObject:[[NSMutableDictionary alloc] init]];

它正在泄漏字典对象,你应该写一下

[dataArray addObject:[NSMutableDictionary dictionary]];

答案 2 :(得分:1)

你的内部循环泄漏了NSMutableDictionary个对象,因为在添加到数组后你应该release它们,即

NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
[dict setObject:[NSString  stringWithFormat:@"%d", sqlite3_column_int(selectstmt, 0)] forKey:@"empID"];
[dict setObject:[NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt,1)] forKey:@"addText"];
[dataArray addObject:dict];
[dict release];

此外,您的整个方法应该最有可能通过命名约定返回自动释放的对象。不确定这是否是泄漏 - 取决于您如何调用该方法以及是否释放返回的值。

所以也许使用

return [dataArray autorelease];

答案 3 :(得分:0)

您的方法包含对+alloc的两次调用,但没有对-release-autorelease的相应调用。

NSMutableArray *dataArray = [[NSMutableArray alloc] init];
...
[dataArray addObject:[[NSMutableDictionary alloc] init]];

你可以像这样重写这些行来消除泄漏:

NSMutableArray *dataArray = [NSMutableArray array];
...
[dataArray addObject:[NSMutableDictionary dictionary]];