Коллекции коллекций и управление памятью Objective-C - PullRequest
1 голос
/ 17 сентября 2009

У меня довольно простой вопрос. Хотя я довольно новичок в Objective-C, я довольно хорошо освоил язык и модель управления памятью.

Я хорошо понимаю владение и понятие явного и неявного. Я также понимаю, что когда вы добавляете что-либо в коллекцию, она берет на себя владение ключами и значениями и освобождает это право собственности при выпуске.

Мой вопрос связан с выпуском коллекции коллекций (aka a Bag). У меня есть следующий код:


    // levelDict is a member NSMutableDictionary on the Class

    BOOL newDict = NO;
    BOOL newArray = NO;

    NSNumber *levelKey = [NSNumber numberWithInt:toLevel];
    NSMutableDictionary *dict = [levelDict objectForKey:levelKey];
    if ( dict == nil ) {
        dict = [[NSMutableDictionary alloc] init];
        [levelDict setObject:dict forKey:levelKey];
        newDict = YES;
    }

    // Now look for the array...
    NSNumber *typeKey = [NSNumber numberWithInt:objectType];
    NSMutableArray *array = [dict objectForKey:typeKey];
    if ( array == nil ) {
        array = [[NSMutableArray alloc] init];
        [dict setObject:array forKey:typeKey];
        newArray = YES;
    }

    // Now add the object to the array...
    [array addObject:object];

    // Deal with our memory management
    if ( newArray ) {
        [array release];
    }

    if ( newDict ) {
        [dict release];
    }

Этот код создает карту, в которой каждая запись содержит массив (он же Bag). Если я выпускаю объект словаря levelDict, который владеет массивом объектов для каждой записи, я предполагаю, что релиз будет каскадно проходить и через массивы? Или мне нужно перебрать словарь и явно освободить каждый из массивов?

Теперь вопрос о дополнительном кредите - почему я делаю это, а не определяю один объект коллекций? Что ж, в других языках, таких как Java, создание объектов может быть очень дорогим. Я предполагаю, что это имеет место с Objective-C. Карты ассоциативных массивов очень эффективны.

Спасибо Bryan

Ответы [ 4 ]

3 голосов
/ 17 сентября 2009

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

Конечно, добавление чего-либо в словарь сохранит ключи и значения, а добавление чего-либо в изменяемый массив сохранит записи.

Довольно просто ...

1 голос
/ 17 сентября 2009

Из руководства по программированию коллекций: http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/Collections/Articles/Arrays.html

"И когда вы добавляете объект в массив Objective C, объект не копируется, а получает сообщение о сохранении до того, как его идентификатор добавляется в массив. Когда массив освобождается, каждому элементу отправляется отпустить сообщение. "

Словари и наборы ведут себя одинаково.

0 голосов
/ 17 сентября 2009

Код проще с помощью авто-выпущенного dict / array, так как ветвление не влияет на счет сохранения.

// levelDict is a member NSMutableDictionary on the Class

NSNumber *levelKey = [NSNumber numberWithInt:toLevel];
NSMutableDictionary *dict = [levelDict objectForKey:levelKey];
if ( dict == nil ) {
    dict = [NSMutableDictionary dictionary];
    [levelDict setObject:dict forKey:levelKey];
}

// Now look for the array...
NSNumber *typeKey = [NSNumber numberWithInt:objectType];
NSMutableArray *array = [dict objectForKey:typeKey];
if ( array == nil ) {
    array = [NSMutableArray array];
    [dict setObject:array forKey:typeKey];
}

// Now add the object to the array...
[array addObject:object];
0 голосов
/ 17 сентября 2009

Пока NSDictionary является единственным контейнером, сохраняющим ссылку на данный NSObject (NSArray в комплекте), он будет освобожден, когда NSDictionary сделает.

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