0

我想弄清楚这段代码中的内存泄漏在哪里?

- (NSMutableArray *) fetchAidDetails:(NSNumber *) rowID {
    NSMutableArray *list = [[NSMutableArray alloc] init];    
    FMDatabase *db = [[FMDatabase databaseWithPath:[self dbPath]] retain];
    if(![db open]) {
        [db release];        
        return [list autorelease];
    }

    NSString *query = [NSString stringWithFormat:@"select legislative_type, legislative_name from legislative_aid where official_id = %d", rowID.unsignedIntValue];

    FMResultSet *result = [[db executeQueryWithFormat:query] retain];

    while ([result next]) {
        NSMutableDictionary *item = [[NSMutableDictionary alloc] init];        
        NSString *type = [[NSString alloc] init];
        type = [result stringForColumn:@"legislative_type"];
        [item setObject:type forKey:@"legislative_type"];
        [type release];

        NSString *party = [[NSString alloc] init];
        party = [result stringForColumn:@"legislative_name"];
        [item setObject:party forKey:@"legislative_name"];
        [party release];

        [list addObject:item];
        [item release];
    }

    [result release];
    [db close];
    [db release];

    return [list autorelease];
}

[item retainCount] 在 [item release] 之​​前给出 2,并且 [list autorelease] 将使引用计数为 0,我这里有什么问题吗?

请帮忙。

谢谢

4

2 回答 2

1
NSString *type = [[NSString alloc] init];
type = [result stringForColumn:@"legislative_type"];

您正在创建一个保留计数为 1 的 NSString“类型”,但随后为其分配了一个不同的对象。删除第一行并使用它:

NSString *type = [result stringForColumn:@"legislative_type"];

您还需要删除[type release]sincestringForColumn返回一个自动释放的 NSString(至少如果它遵守 Cocoa 命名约定)。

于 2012-10-03T16:39:30.270 回答
0
  • 不要依赖retainCount。系统或类的内部代码可以在内部保留您的对象并在以后发布它,这是他们的业务,您无法知道,因此您真的不知道在retainCount. 这不是寻找泄漏的好方法

  • 在您的代码中多次分配一个对象(在您的情况下是一个NSString),然后忽略它以使用其他值覆盖变量:

    NSString *party = [[NSString alloc] init]; // You allocate memory for an NSString object
    party = [result stringForColumn:@"legislative_name"]; // then you completely forget about it and override your party variable with a different object
    

就像你在做的那样:

int i = 5;
i = 12;

当然,第一个值是无用的,也不需要。但是对于您的代码,您从不使用的这个值分配的内存永远不会被回收,因此它会泄漏。

  • 然后,在您将另一个对象影响到您的party变量之后,您稍后将 a 发送release到这个新对象。但是party已经包含了一个自动释放的对象,正如您[result stringForColumn:xxx]对它的影响,并且根据代码命名约定,此方法返回一个自动释放的对象。所以你不需要release在这个新对象上发送一个。

所以你的循环应该看起来像下面这样:

while ([result next])
{
  @autoreleasepool {
    NSMutableDictionary *item = [[NSMutableDictionary alloc] init];        
    NSString *type = [result stringForColumn:@"legislative_type"];
    [item setObject:type forKey:@"legislative_type"];

    NSString *party = [result stringForColumn:@"legislative_name"];
    [item setObject:party forKey:@"legislative_name"];

    [list addObject:item];
    [item release];
  }
}
于 2012-10-03T16:46:18.970 回答