2011-01-07 2 views
2

У меня проблемы с пониманием свойств. Какое свойство следует писать, если я хочу, чтобы атрибут не был изменен его аксессуарами (возврат по копии) и был установлен по ссылке (сохранить).Наличие свойств, возвращающих копии объектов в геттере, и сохранение объектов в сеттере

Пример:

MyType* theAttribute = MyObject.attribute; 
[theAttribute changeSomething]; // Does not have to change the MyObject attribute, working with a copy return 

MyType tmpObject = [[MyType alloc] init]; 
MyObject.attribute = tmpObject; // Want a retain here 
[tmpObject release]; 

ответ

4

объявить свойство, как сохранить в заголовке:

@property (nonatomic. retain) MyType *attribute; 

В файле реализация синтез Ивара:

@synthesize attribute; 

Но предоставить собственный поглотитель, переназначающие синтезированный один:

- (MyType)attribute { 
    return [attribute copy]; 
} 

Я знаю, что я не autoreleasing возвращаемого объекта, но поскольку вопрос не указывает iOS, я пишу это с точки зрения среды сбора мусора.

+1

Поскольку «атомный» по умолчанию, вам также нужно написать «setter». Вы не можете смешивать синтезированные геттеры с вручную написанными сеттерами или наоборот. (GCC может пропустить этот пропуск, но это неправильно. LLVM 2.0 правильно предупреждает/ошибки на таких махинациях.) – bbum

+1

Спасибо, Билл. Я исправил свой ответ – Abizern

2

В таком случае вы должны написать геттер и сеттер самостоятельно.

+0

Вам не нужно писать сеттер самостоятельно, просто получателем. – Abizern

+0

Да, действительно, я пропустил это. Благодарю. –

+0

Вам нужно будет написать установщик самостоятельно, если вы хотите использовать 'atomic'. – bbum

1

Вы, наверное, написать свой собственный аксессор (ы), но как именно, зависит от того, хотите ли вы скопировали «получить» вернуться быть autoreleased или нет:

  1. идиоматических способ выполнения «копия «это должно иметь нормальное свойство« сохранить »для аксессуаров и поддерживать метод -copy или -mutableCopy. Последние два являются стандартом для семантического копирования объекта, а возвращаемый объект должен иметь право собственности.

  2. Если вы хотите иметь аксессор -foo вернуть копию «Foo», так что абонент не может манипулировать внутренней версии, это нормально, но тогда вы бы написать его самостоятельно, чтобы выглядеть следующим образом:

-

- (Foo *)foo 
{ 
    return [[foo copy] autorelease]; 
} 
+0

Uhhh ... Не [foo copy] возвращает сохраненный объект? Автореализацию сохраненного объекта? – Oliver

+0

@Oliver: Да, '[foo copy]' возвращает сохраненный объект, но по соглашению, getter '-foo' не должен, следовательно, автореклама. Результирующий эффект - это то, что хочет вызываемый (копия исходных данных) и то, что ожидает вызывающий (объект, который можно отбросить без явного вызова выпуска). –

-2

Я предлагаю не возвращать копию. Это задержит вас в управлении памятью. Автоматически выпущено? Не удалось? Слишком много вопросов.

Вместо этого я рекомендую это:

MyType* attr = [MyType typeWithMyType:MyObject.attribute]; 

или что-то.

+1

Нет вопросов, если вы будете следовать правилам управления памятью; Методы возвращают автореализованные объекты, и вы освобождаете только то, что вы выделяете, сохраняете, копируете или изменяете. Кроме того, этот способ требует, чтобы потребитель класса использовал копию и не менял объект, а передача копии обеспечивала это по дизайну, который освобождается от беспокойства о том, копировать ли значения, возвращаемые геттерами или нет. – Abizern

+0

Но вот в чем дело. Свойство keep'd, которое возвращает автореализованную копию, нарушает все эти правила и соглашения об именах. –

+0

Почему? Геттер не влияет на объект, сохраненный как свойство, и просто возвращает копию. Как управление памятью _copy_ влияет на управление памятью _original_? – Abizern

Смежные вопросы