释放包含NSDictionary对象的NSArray

时间:2010-01-23 07:24:50

标签: iphone objective-c cocoa memory-management memory-leaks

我在iPhone SDK 3.1的以下代码段中难以理解内存管理。

// Create array to hold each PersonClass object created below
NSMutableArray *arrayToReturn = [[[NSMutableArray alloc] init] autorelease];

NSArray *arrayOfDictionaries = [self generateDictionaryOfPeople];

[arrayOfDictionaries retain];

for (NSDictionary *dictionary in arrayOfDictionaries) {

    PersonClass *aPerson = [[PersonClass alloc] init];

    for (NSString *key in [dictionary keyEnumerator]) {

        if ([key isEqualToString:[[NSString alloc] initWithString: @"FIRST_NAME"]])
            aPerson.firstName = [dictionary objectForKey:key];

        else if ([key isEqualToString:[[NSString alloc] initWithString: @"LAST_NAME"]])
            aPerson.lastName = [dictionary objectForKey:key];

    }

    // Add the PersonClass object to the arrayToReturn array
    [arrayToReturn addObject: aPerson];

    // Release the PersonClass object
    [aPerson release];

}

return arrayToReturn;

[self generateDictionaryOfPeople]方法返回NSDictionary对象的数组。每个NSDictionary对象都有两个键“FIRST_NAME”和“LAST_NAME”,其中一个人的名字和姓氏作为相应的数据。代码循环遍历arrayOfDictionaries数组中的每个字典对象,并将字典数据分配给aPerson(PersonClass)对象的相关属性。然后将此对象添加到从此方法返回的数组中。

运行仪器时,我收到arrayOfDictionaries数组中包含的字典对象的泄漏。 [self generateDictionaryOfPeople]方法中的代码在每个NSDictionary对象上创建并添加到数组时调用[dictionaryObject release],这使得对象1上的保留计数(因为将对象添加到数组中会使保留计数2,但随后我的释放消息将其减少回1)。

我认为这个泄漏是因为我从不发布arrayOfDictionaries数组,因此数组中的NSDictionary对象永远不会被释放。如果我尝试在上面的代码段结束时释放数组,我会收到“发送到解除分配的实例的消息”错误。我理解为什么会发生这种情况,因为我在字典项中分配aPerson对象数据(我随后发布)但我不知道我还能在哪里发布arrayOfDictionaries数组。任何帮助将不胜感激。

谢谢!

编辑:以下是[self generateDictionaryOfPeople]

的实施方案
- (NSArray *)generateDictionaryOfPeople {

    NSMutableArray *arrayFromDatabase = [[[NSMutableArray alloc] init] autorelease];

    // ** Query the database for data **

    while ( there are rows being returned from the database ) {

        // Declare an NSMutableDictionary object
        NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];

        // Loop through each column for that row
        for ( while there are columns for this row ) {

            columnTitle = title_of_column_from_database
            columnData = data_in_that_column_from_database

            // Add to the dictionary object
            [dictionary setObject:columnData forKey:columnTitle];

            // Release objects
            [columnName release];
            [columnTitle release];

        }

        // Add the NSMutableDictionary object to the array
        [arrayFromDatabase addObject:dictionary];

        // Release objects
        [dictionary release];

    }

    // Return the array
    return arrayFromDatabase;

}

3 个答案:

答案 0 :(得分:3)

下面,

    if ([key isEqualToString:[[NSString alloc] initWithString: @"FIRST_NAME"]])
        aPerson.firstName = [dictionary objectForKey:key];

    else if ([key isEqualToString:[[NSString alloc] initWithString: @"LAST_NAME"]])
        aPerson.lastName = [dictionary objectForKey:key];

替换它们
    if ([key isEqualToString:@"FIRST_NAME"])
        aPerson.firstName = [dictionary objectForKey:key];

    else if ([key isEqualToString:@"LAST_NAME"])
        aPerson.lastName = [dictionary objectForKey:key];

泄漏问题是你在没有NSString的情况下每循环创建1~2 -release - s。如果您需要常量NSString - s,只需直接使用它们。

答案 1 :(得分:1)

  

由于没有释放arrayOfDictionaries数组,我仍然得到原始泄漏。

这意味着您忘记在generateDictionaryOfPeople中自动发布。

您需要查看the memory management rules

答案 2 :(得分:1)

您没有发布arrayFromDatabase。 (避免这种错误的最简单方法是尽早使用工厂和autorelease而不是手动推迟发布。在这种情况下,请使用[NSMutableDictionary dictionary]而不是[[NSMutableDictionary alloc] init]。)< / p>