简体   繁体   English

发布包含NSDictionary对象的NSArray

[英]Releasing NSArray containing NSDictionary objects

I am having difficulty getting my head around memory management in the following segment of code on iPhone SDK 3.1. 在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;

The [self generateDictionaryOfPeople] method returns an array of NSDictionary objects. [self generateDictionaryOfPeople]方法返回NSDictionary对象的数组。 Each NSDictionary object has two keys "FIRST_NAME" and "LAST_NAME" with a person's first name and last name as the respective data. 每个NSDictionary对象都有两个键“ FIRST_NAME”和“ LAST_NAME”,并以一个人的名字和姓氏作为各自的数据。 The code is looping through each dictionary object in the arrayOfDictionaries array and assigning the dictionary data to the relevant property of an aPerson (PersonClass) object. 代码遍历arrayOfDictionaries数组中的每个字典对象,并将字典数据分配给aPerson(PersonClass)对象的相关属性。 This object is then added to an array which is returned from this method. 然后将此对象添加到此方法返回的数组中。

When running instruments I am getting a leak for the dictionary objects contained in the arrayOfDictionaries array. 运行乐器时,我发现arrayOfDictionaries数组中包含的字典对象泄漏。 The code within the [self generateDictionaryOfPeople] method is calling [dictionaryObject release] on each NSDictionary object as it is created and added to the array, which makes the retain count on the object 1 (as adding the object to the array would make the retain count 2, but then my release message decrements it back to 1). [self generateDictionaryOfPeople]方法中的代码在创建每个NSDictionary对象并将其添加到数组时,在每个NSDictionary对象上调用[dictionaryObject release] ,这使对象1的保留计数(因为将对象添加到数组将使保留计数2,但随后我的发布消息将其递减回1)。

I assume this leak is because I am never releasing the arrayOfDictionaries array, and thus the NSDictionary objects within the array are never released. 我认为这种泄漏是因为我从未发布过arrayOfDictionaries数组,因此该数组内的NSDictionary对象也从未发布过。 If I attempt to release the array at the end of the above segment of code I get a "message sent to deallocated instance" error. 如果我尝试在上述代码段的末尾释放数组,则会收到“发送到已释放实例的消息”错误。 I understand why this is occurring, because I am assigning the aPerson object data within a dictionary item (that I am subsequently releasing) but I don't know where else I can release the arrayOfDictionaries array. 我知道为什么会这样,因为我正在将aPerson对象数据分配到词典项(随后要发布)中,但是我不知道还能在哪里发布arrayOfDictionaries数组。 Any help would be greatly appreciated. 任何帮助将不胜感激。

Thanks! 谢谢!

EDIT: Below is the implementation for [self generateDictionaryOfPeople] 编辑:以下是[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;

}

Here, 这里,

    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];

Replace them with 替换为

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

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

The problem of the leak is you're creating 1 ~ 2 NSString -s per loop without -release -ing them. 泄漏的问题是您在每个循环中创建NSString -s而不用-release -ing它们。 If you need constant NSString -s, just directly use them. 如果需要恒定的NSString -s,则直接使用它们。

I am still getting the original leak due to not releasing the arrayOfDictionaries array. 由于未释放arrayOfDictionaries数组,我仍然遇到原始泄漏。

That means you forgot to autorelease it in generateDictionaryOfPeople . 这意味着您忘记了在generateDictionaryOfPeople自动释放它。

You need to review the memory management rules . 您需要查看内存管理规则

You are not releasing arrayFromDatabase . 您没有释放arrayFromDatabase (The simplest way to avoid this kind of mistake is to use factories and autorelease as early as possible rather than defer releases manually. In this case, use [NSMutableDictionary dictionary] instead of [[NSMutableDictionary alloc] init] .) (避免这种错误的最简单方法是尽早使用工厂和autorelease ,而不是手动推迟释放。在这种情况下,请使用[NSMutableDictionary dictionary]而不是[[NSMutableDictionary alloc] init] 。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM