2011-01-19 2 views
4

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

Код:

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 неявное «сохранение»? Если это так, я должен был как-то это понять, или это просто одна из тех вещей, которые вы должны читать и помнить?

ответ

1

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

См. Руководство Collections Programming Topics от Apple.

4

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

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

3

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

-addObject: forKey:

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

-removeAllObjects

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

4

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

Путь думать об этом так:

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

2) Теперь сбор и я оба имеют право собственности на этот объект

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

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

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

+1

Я переключился на размышления о владельцах, а не именах методов. Если я непосредственно владею коллекцией, и она непосредственно владеет объектами, которые я вставляю в нее, я рассматриваю это как свое * косвенное * владение всеми объектами в коллекции, без * непосредственно * владеющих ими в одно и то же время. Мой аргумент в пользу этого - это еще одно, что нужно помнить, чтобы очистить; Я приветствую аргументы против. –

+0

Я бы сказал, что эта модель становится более сложной из-за того, что нужно отслеживать, какие объекты фактически захватывают вещи, которые вы им передаете. Вещи, которые копируют свои аргументы, нет, слабые коллекции нет, делегаты не делают и т. Д. ... все это интуитивно для вас и для меня, но для обучения нового программиста какао много концепций. Модель локального * владения «я владею этим, пока я его использую» не требует мышления о других объектах. –

+1

Более кратко, косвенные модели владения способствуют сцеплению. –