#iphone #memory-management
#iPhone #управление памятью
Вопрос:
Возможно, это глупый вопрос, но во введении к tableViews автор использует свойство NSArray * listData для заполнения таблицы фиктивными данными. В viewDidLoad он в основном делает это:
- (void)viewDidLoad {
NSArray *array = [[NSArray alloc] initWithObjects@"1", @"2", @"3", more stuff, nil];
self.listData = array;
[array release];
...
}
Почему он создает другой массив и присваивает ему свойство, а не делает что-то вроде
- (void)viewDidLoad {
listData = [[[NSArray alloc] initWithObjects@"1", @"2", @"3", more stuff, nil]autorelease];
Можно ли лучше управлять памятью, используя alloc / init по сравнению с пулом автоматического освобождения? Или второй способ просто не сработает? Спасибо.
Ответ №1:
Ваш код неверен и, вероятно, приведет к сбою. В своем коде он вызывает alloc
, что означает, что количество сохранений равно 1. Затем он присваивает его свойству. Я предполагаю, что это свойство объявлено равным retain
, и в этом случае количество сохранений увеличится до 2. Затем он вызвал release
, который возвращает количество сохранений обратно к 1.
В вашем коде вы вызываете alloc
, что означает, что количество сохраняемых данных равно 1, затем вы вызываете autorelease
, что означает, что количество сохраняемых данных упадет до 0, и память объекта скоро будет освобождена. Вы присваиваете объект переменной экземпляра — не сохраняемому свойству, как это делает he, — поэтому вы больше не будете увеличивать количество сохраняемых данных. Это означает, что вы останетесь с зависшим указателем на память, который в любой момент может быть перезаписан чем-либо другим. При попытке доступа listData
произойдет сбой, поскольку файл, скорее всего, был перезаписан.
Пожалуйста, прочтите руководство по программированию управления памятью, если вы не понимаете, что здесь происходит.
Сказав это, суть вашего вопроса верна. Ничто не мешает ему делать то же самое, что и вы, за исключением присвоения сохраненному свойству вместо переменной экземпляра.
Комментарии:
1. Я все еще привыкаю к «себе». В моем фрагменте кода я имел в виду ссылаться на свойство listData, которое также было объявлено с помощью функции retain . Должен ли я иметь self в этом случае, чтобы ссылаться на это свойство? В противном случае это ivar только в рамках этого метода? (Извините, некоторые из OOAD, props, ivar все еще загружаются). Спасибо.
2. Когда вы объявляете и синтезируете свойство, создается переменная экземпляра с тем же именем, а также средства получения и установки. Если свойство объявлено для
retain
, то когда вы присваиваете объекту свойство, синтезированный установщик отправит этому объектуretain
сообщение. Если вы не используетеself.
, то вы не присваиваете свойство, вы обходите установщик и присваиваете непосредственно переменной экземпляра, поэтому количество сохраняемых объектов не увеличится.3. На самом деле дело не в области видимости. Переменная экземпляра — это переменная, которая является частью объекта (объект — это просто экземпляр класса). Область имеет значение только потому, что автоматически освобожденный объект с числом сохранений 0 гарантированно не будет освобожден только в текущей области (более или менее).