Как правильно выпустить переменную экземпляра NSMutableDictionary с вложенными словарями в Objective-C? - PullRequest
1 голос
/ 10 сентября 2009

У меня есть класс Objective-C, который выглядит примерно так:

@interface myClass : NSObject
{
    NSMutableDictionary *aDict;
}

Его метод установки выглядит так:

- (void) setADict: (NSMutableDictionary *) newDict
{
    [aDict release];
    [newDict retain];
    aDict = newDict;
}

Я создал экземпляр объекта, поместил данные в aDict и теперь хочу избавиться от объекта, очистив его память в процессе. Два вопроса:

1) Должен ли я выпустить aDict в myClass dealloc , как показано?

[aDict release];

=============================================== ==============================

2) Я вложил несколько дочерних словарей в aDict , представленный keyA и keyB , например:

// aDict:
{
    keyA =     {
        keyA1 = "Hello world";
        keyA2 = 1234;
    };
    keyB =     {
        keyB1 = Earth;
        keyB2 = 25000;
    };
}

Будет ли сообщение [aDict release]"распространяться по цепочке" и очистить все дочерние словари внутри aDict, включая их объекты ключ / значение? Или я должен сделать что-то еще, чтобы избавиться от них?

Ответы [ 2 ]

4 голосов
/ 10 сентября 2009

Да.

Объекты коллекции сохраняют вещи, которые они собирают, поэтому, когда коллекция освобождается, она уравновешивает хранение с выпуском.

Затем, если один из словарей, на которых он держался, освобождается, он также освобождает свои пары ключ / значение, поскольку словарь является коллекцией, а объекты коллекции сохраняют то, что собирают.

То же самое относится и к массивам и наборам.

Однако в вашем коде есть ошибка. У вас есть:

- (void) setADict: (NSMutableDictionary *) newDict
{
    [aDict release];
    [newDict retain];
    aDict = newDict;
}

Рассмотрим случай, когда newDict - это тот же объект, что и aDict. Затем вы освобождаете словарь, он освобождается, и затем вы пытаетесь сохранить его, но упс! Его больше нет.

Есть три варианта исправления. Вот они:

    - (void) setADict: (NSMutableDictionary *) newDict
    {
        [aDict autorelease];
        [newDict retain];
        aDict = newDict;
    }

    - (void) setADict: (NSMutableDictionary *) newDict
    {
      if (aDict != newDict) {
        [aDict release];
        [newDict retain];
        aDict = newDict;
      }
    }

    - (void) setADict: (NSMutableDictionary *) newDict
    {
        [newDict retain];
        [aDict release];
        aDict = newDict;
    }

Я бы сказал, что третий самый простой, второй самый быстрый со временем, а первый - meh . Первый будет загромождать ваши пулы авто-релиза (что может или не может привести к переполнению памяти). Второе и третье эквивалентны с точки зрения безопасности и управления памятью свойств. Тем не менее, второй сэкономит вам ненужные вызовы методов, если вы устанавливаете тот же словарь на себя.

2 голосов
/ 10 сентября 2009

NSMutableDictionary освободит все объекты (значения) при выпуске.

NSMutableDictionary копирует ключ и отправляет сохранение в значение для каждой пары ключ / значение, которую вы добавили. Практика какао такова, что когда что-то сохраняет ссылку, оно отвечает за ее освобождение.

См. Ссылку NSMutableDictionary

Методы, которые добавляют записи в словари - как часть инициализация (для всех словарей) или во время модификации (для изменяемого словари) - скопируйте каждый ключевой аргумент (ключи должны соответствовать NSCopying протокол) и добавить копии в толковый словарь. Каждое соответствующее значение объект получает сообщение сохранения убедитесь, что он не будет освобожден до того, как словарь закончен с это.

...