Атрибут свойства “сохранить”, похоже, не работает?
-
06-07-2019 - |
Вопрос
Я реализовал немного кода из одного из многочисленных примеров Apple code, но у меня возникли небольшие проблемы, потому что атрибут retain одного из свойств, похоже, не работает.Вот декларация о собственности:
@property (nonatomic, retain) EditingViewController *editingViewController;
И вот этот код:
- (EditingViewController *)editingViewController {
// Instantiate the editing view controller if necessary.
if (editingViewController == nil) {
EditingViewController *aController = [[EditingViewController alloc] init];
editingViewController = aController;
[aController release];
}
return editingViewController;
}
Я понимаю, что (retain) должно приводить к увеличению количества сохранений на 1 при назначении;однако код завершается с ошибкой, если я делай отправьте [aController retain] меня самого, или не надо отправить [релиз aController].Чего я здесь не понимаю?
Решение
Когда вы ссылаетесь editingViewController
, это эквивалентно self->editingViewController
, т. е.доступ к ivar.
Если вы хотите использовать геттер или сеттер, вам необходимо использовать self.editingViewController
, или эквивалентно [self setEditingViewController:aController]
.
Вот почему я предпочитаю использовать ivar с именем, отличным от имени свойства, например:
EditingViewController* i_editingViewController;
@property (nonatomic, retain) EditingViewController *editingViewController;
@synthesize editingViewController = i_editingViewController;
Тогда вы можете написать свой ленивый геттер следующим образом:
- (EditingViewController *)editingViewController {
// Instantiate the editing view controller if necessary.
if (i_editingViewController == nil) {
i_editingViewController = [[EditingViewController alloc] init];
}
return i_editingViewController;
}
или
- (EditingViewController *)editingViewController {
// Instantiate the editing view controller if necessary.
if (i_editingViewController == nil) {
EditingViewController *aController = [[EditingViewController alloc] init];
self.editingViewController = aController;
[aController release];
}
return i_editingViewController;
}
Я бы, вероятно, использовал первый метод (не вызывая установщик), потому что значение editingViewController
(как видит любой наблюдатель) на самом деле не изменился, но в любом случае должен работать нормально, а другое имя (для ivar и property) поможет избежать путаницы или случайного неправильного использования.Это также мягкое поощрение к использованию свойства (поскольку оно позволяет избежать слегка уродливого префикса).
Обратите внимание, что Apple оставляет за собой префикс _ и что установщики и геттеры не должны использоваться в init
/dealloc
рутина.
Другие советы
Вы должны написать self.editingViewController
, чтобы использовать это свойство. Просто editViewController
" является прямым доступом к переменной-члену Class, тогда как self.editingViewController
эквивалентен [self setEditingViewController: ...] и будет выполнять соответствующую работу сохранения / освобождения.