Атрибут свойства "сохранить" не работает? - PullRequest
2 голосов
/ 01 августа 2009

Я реализовал немного кода из одного из множества примеров кода Apple, но у меня возникли некоторые проблемы, потому что атрибут 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;
}

Я понимаю, что (удержание) должно привести к увеличению количества удержаний на 1 при назначении; однако код завершится ошибкой, если я не отправлю [aController retain] сам, или не отправлю [релиз aController]. Что мне здесь не хватает?

Ответы [ 2 ]

4 голосов
/ 01 августа 2009

Когда вы ссылаетесь на editingViewController, это эквивалентно self->editingViewController, то есть доступу к ивару.

Если вы хотите использовать геттер или сеттер, вам нужно использовать self.editingViewController, или эквивалентно [self setEditingViewController:aController].

Именно поэтому я предпочитаю использовать ивар с другим именем для свойства, например:

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 и свойства) ) поможет избежать путаницы или случайного неправильного использования. Это также мягкое поощрение использования свойства (так как оно избегает слегка уродливого префикса).

Обратите внимание, что Apple резервирует префикс _, и что сеттеры и геттеры не должны использоваться в подпрограммах init / dealloc.

0 голосов
/ 01 августа 2009

Вы должны написать self.editingViewController, чтобы использовать собственность.Просто «editingViewController» - это прямой доступ к переменной члена класса, тогда как self.editingViewController эквивалентен [self setEditingViewController: ...] и будет выполнять соответствующее задание сохранения / освобождения.

...