Как правильно освободить переменную экземпляра NSMutableDictionary с вложенными словарями в Objective-C?
-
05-07-2019 - |
Вопрос
У меня есть класс Objective-C, который выглядит примерно так:
@interface myClass : NSObject
{
NSMutableDictionary *aDict;
}
Его метод установки выглядит следующим образом:
- (void) setADict: (NSMutableDictionary *) newDict
{
[aDict release];
[newDict retain];
aDict = newDict;
}
Я создал экземпляр объекта, поместил данные в aDict и теперь хочу избавиться от объекта, очистив его память в процессе.Два вопроса:
1) Должен ли я отпустить аДикт в MyClass ( Мой класс )'s освободить место метод, как показано?
[aDict release];
=============================================================================
2) Я вложил несколько дочерних словарей в аДикт, представленный кейЯ и Клавиша B, вот так:
// aDict:
{
keyA = {
keyA1 = "Hello world";
keyA2 = 1234;
};
keyB = {
keyB1 = Earth;
keyB2 = 25000;
};
}
Будет ли [Рекламный релиз] сообщение "распространить по цепочке" и очистить все дочерние словари внутри aDict, включая их объекты ключа / значения?Или я должен сделать что-то еще, чтобы избавиться от них?
Решение
ДА.
Объекты коллекции сохраняют то, что они собирают, поэтому, когда коллекция освобождается, она уравновешивает сохранение выпуском.
Затем, если один из словарей, в котором он хранился, будет освобожден, он также освободит свои пары ключ / значение, поскольку словарь является коллекцией, а объекты коллекции сохраняют то, что они собирают.
То же самое справедливо для массивов и множеств.
Однако у вас есть ошибка в вашем коде.У вас есть:
- (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;
}
Я бы сказал, что третий способ самый простой, второй - самый быстрый по времени, а первый ме.Первый приведет к загромождению ваших пулов авторелиза (что может привести, а может и не привести к раздуванию памяти).Второй и третий эквивалентны с точки зрения безопасности и управления памятью свойств.Однако второй вариант избавит вас от ненужных вызовов метода, если вы случайно устанавливаете один и тот же словарь поверх самого себя.
Другие советы
NSMutableDictionary
освободит все объекты (значения) при выпуске.
NSMutableDictionary
копирует ключ и отправляет retain в value для каждой добавленной вами пары ключ / значение.Практика Cocoa заключается в том, что когда что-то сохраняет ссылку, то оно несет ответственность за ее освобождение.
Смотрите ссылку на NSMutableDictionary
Методы, которые добавляют записи в словари — будь то как часть инициализации (для всех словарей) или во время модификации (для изменяемых словарей) — скопируйте каждый ключевой аргумент (ключи должны соответствовать протоколу NSCopying ) и добавьте копии в словарь.Каждому соответствующему значению объект получает сообщение о сохранении, чтобы гарантировать, что оно не будет освобождено до завершения работы словаря с ним.