Выпуск NSArray, содержащий объекты NSDictionary - PullRequest
2 голосов
/ 23 января 2010

У меня возникают проблемы с управлением памятью в следующем сегменте кода на 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] вызывает [dictionaryObject release] для каждого объекта NSDictionary при его создании и добавлении в массив, что делает счет сохранения для объекта 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 ]

3 голосов
/ 23 января 2010

Здесь

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

Проблема утечки заключается в том, что вы создаете 1 ~ 2 NSString -с за цикл без -release -из них. Если вам нужны постоянные NSString -s, просто используйте их напрямую.

1 голос
/ 23 января 2010

Вы не выпускаете arrayFromDatabase. (Самый простой способ избежать этой ошибки - использовать фабрики и autorelease как можно раньше, а не откладывать выпуск вручную. В этом случае используйте [NSMutableDictionary dictionary] вместо [[NSMutableDictionary alloc] init].)

1 голос
/ 23 января 2010

Я все еще получаю исходную утечку из-за того, что не освобождаю массив arrayOfDictionaries.

Это означает, что вы забыли автоматически выпустить его в generateDictionaryOfPeople.

Вам необходимо просмотреть правил управления памятью .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...