0

仪器在以下代码中显示内存泄漏。我确保在任何地方都保持保留计数。我还添加了自动释放池,仍然存在内存泄漏。如何解决这个问题?

代码块:

- (NSArray *)lookupAllForSQL:(NSString *)sql
{
    sqlite3_stmt *statement;
    id result = nil;
    NSMutableArray *thisArray = [NSMutableArray arrayWithCapacity:4];
    statement = [self prepare:sql];
    if (statement)
    {
        while (sqlite3_step(statement) == SQLITE_ROW)
        {
            NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

            NSMutableDictionary *thisDict = [NSMutableDictionary dictionaryWithCapacity:4];
            for (int i = 0 ; i < sqlite3_column_count(statement) ; i++)
            {
                NSAutoreleasePool *poolInside = [[NSAutoreleasePool alloc] init];
                if(sqlite3_column_type(statement,i) == SQLITE_NULL)
                {
                    continue;
                }
                if (sqlite3_column_decltype(statement,i) != NULL &&
                    strcasecmp(sqlite3_column_decltype(statement,i),"Boolean") == 0)
                {
                    result = [NSNumber numberWithBool:(BOOL)sqlite3_column_int(statement,i)];
                }
                else if (sqlite3_column_type(statement,i) == SQLITE_INTEGER)
                {
                    result = [NSNumber numberWithInt:(int)sqlite3_column_int(statement,i)];
                }
                else if (sqlite3_column_type(statement,i) == SQLITE_FLOAT)
                {
                    result = [NSNumber numberWithFloat:(float)sqlite3_column_double(statement,i)];
                }
                else
                {
                    if((char *)sqlite3_column_text(statement,i) != NULL)
                    {
                        //result = [NSString stringWithUTF8String:(char *)sqlite3_column_text(statement,i)];
                        [thisDict setObject:[NSString stringWithUTF8String:(char *)sqlite3_column_text(statement,i)]
                                     forKey:[NSString stringWithUTF8String:sqlite3_column_name(statement,i)]];
                        //[result release];
                        result = nil;
                    }
                }
                if (result)
                {
                    [thisDict setObject:result forKey:[NSString stringWithUTF8String:sqlite3_column_name(statement,i)]];
                }
                [poolInside drain];
            }
            [thisArray addObject:[NSDictionary dictionaryWithDictionary:thisDict]];
            [pool drain];
        }
    }
    sqlite3_finalize(statement);
    return thisArray;
}

仪器截图:

在此处输入图像描述

4

2 回答 2

0

我得到了解决方案。这个函数返回一个 NSArray,我没有正确释放它。因此,所有这些变量都导致了内存泄漏,而不是这个函数。

这个视频帮助我理解了这一点。

于 2013-05-30T16:26:48.110 回答
0

我认为这种continue说法可能有问题。由于continue语句导致该控制进入最近循环的下一个迭代,如果条件(sqlite3_column_type(statement,i) == SQLITE_NULL)true控制将传递到下一个迭代并且“poolInside”池不会被耗尽。所以我会使用:

if(sqlite3_column_type(statement,i) == SQLITE_NULL)
{
    [poolInside drain];
    continue;
}

但是,这可能是您为解决泄漏而添加的错误,因此来自@CodaFi 的评论仍然有效。

为了完整起见

如果大家看一下poolInside泄漏的后果,可以看到这一行:

[thisArray addObject:[NSDictionary dictionaryWithDictionary:thisDict]];

NSDictionary每次泄漏都会泄漏一个poolInside。因此,这意味着返回的数组将包含泄漏的对象。另外,我怀疑泄漏嵌套的 NSAutoreleasePool 可能会导致在 for 循环中创建的对象也被泄漏。我认为您发布的“仪器屏幕截图”显示了这种行为。

于 2013-05-30T15:25:45.763 回答