Нужна помощь в понимании конкретной идиомы alloc / release в программировании на iOS / Objective-C - PullRequest
4 голосов
/ 19 января 2011

Я опытный программист C / C ++, начинающий изучать разработку Objective-C.В настоящее время я просматриваю образец UICatalog и натолкнулся на еще один пример идиомы, которую я видел в нескольких местах и ​​никогда не понимал.

Код:

ButtonsViewController *buttonsViewController = [[ButtonsViewController alloc] initWithNibName:@"ButtonsViewController" bundle:nil];
[self.menuList addObject:[NSDictionary dictionaryWithObjectsAndKeys:
                                       NSLocalizedString(@"ButtonsTitle", @""), kTitleKey,
                                       NSLocalizedString(@"ButtonsExplain", @""), kExplainKey, 
                                       buttonsViewController, kViewControllerKey, nil]];
[buttonsViewController release];

AFAIK, он выделяет и инициализирует ButtonsViewController, создает NSDictionary для ButtonsViewController и добавляет словарь в NSMutableArray с именем menuList (который является переменной-членом MainViewControllerгде живет приведенный выше код), а затем выпускает только что созданный buttonViewController.Позже, MainViewController использует словарную запись для переключения представлений на buttonViewController, когда это необходимо.

Мой вопрос: почему buttonViewController остается действительным после этого кода?Он был распределен и выпущен без «удержаний» между ними.Имеет ли добавление чего-либо к NSDictionary или NSMutableArray неявное «сохранение»?Если да, то должен ли я как-то это выяснить, или это одна из тех вещей, которую вы должны прочитать и запомнить?

Ответы [ 4 ]

4 голосов
/ 19 января 2011

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

Способ думать об этом таков:

1) У меня есть право собственности на этот объект, который я создал

2) Теперь и я, и коллекция владеем этим объектом

3) Теперь только коллекция, и я не должен использовать объект, потому что у меня нет владения им

и игнорируйте тот факт, что технически вы можете сойти с рук, не обращая внимания на 3. В этом случае

Это позволяет вам продолжать использовать правило NARC (new-alloc-retain-copy) для размышлений о том, что сохраняет объекты.

4 голосов
/ 19 января 2011

Это стандартная процедура в структурах Какао для коллекций для сохранения объектов, которые они содержат. Так что да, изменяемый массив сохраняет контроллер представления.

Это всегда так, если в документации не указано иное.

3 голосов
/ 19 января 2011

Как уже упоминалось, NSDictionary и NSArray отправляют сохраняемые сообщения добавленным объектам, а также отправляют выпуск объектам при удалении.Приведенный выше код концептуально передает владение кнопкамиViewViewController в словарь.Пример того, как вы можете узнать это ... из документации:

-addObject: forKey:

Параметры: anObject - Значение для ключа.Объект получает сообщение сохранения перед добавлением в словарь.Это значение не должно быть nil.

-removeAllObjects

Обсуждение: каждому ключу и соответствующему объекту значения отправляется сообщение об освобождении.

1 голос
/ 19 января 2011

Да, контейнеры, такие как NSDictionary и NSMutableArray, сохраняют (или копируют, в случае ключей словаря) объекты, которые вы в них помещаете.

См. Руководство по программированию коллекций от Apple.

...