2013-08-27 6 views
0

Я знаю, что при использовании ARC и у вас есть свойство NSString, вы делаете @property(nonatomic, copy) так же, как и MRC. Но я задаюсь вопросом, после того, как я преобразовал свой проект в АРК, я до сих пор это в моем методе инициализации:«Копировать» при использовании ARC

_someString = [someStringParameter copy] 

Является ли это ошибка? Или даже с ARC, мне еще нужно явно сказать «copy»? Или я должен просто:

self.someString = someStringParameter 

и все будет ОК? Бит путать здесь ...

ответ

1
_someString = [someStringParameter copy]; 

Является ли это ошибка?

No.

Или даже с ARC, мне еще нужно явно сказать "копия"?

Абсолютно.

Вы назначаете переменную экземпляра копией, и она абсолютно законна при использовании ARC. В противоположность этому, делая только:

_someString = someStringParamenter; 

заставит ARC автоматически сохранять (не копировать) его, в результате чего-то вроде

_someString = [someStringParameter retain]; 

Это происходит потому, что при ARC переменных имеют неявный __strong идентификаторов, если указано иначе.


self.someString = someStringParameter 

Это правильно, и как по АРК и MRC вы получите объект, который будет скопирован, если вы предоставили атрибут copy в объявлении свойства.

Тем не менее, это еще плохой идеей, чтобы использовать методы доступа в инициализаторах, поскольку они могут иметь нежелательные побочные эффекты, если у вас есть пользовательская реализация для них. Ответьте на этот вопрос: Should I refer to self.property in the init method with ARC?

+0

Спасибо за ответ. Я никогда не переоцениваю методы свойств, поэтому я и делаю это. Иногда я сталкиваюсь с тем, что мне приходится вызывать метод из инициализатора, который обращается к свойствам, и я также должен вызывать тот же самый метод из кода где-то. Как вы справляетесь с этой ситуацией? Должны ли свойства в указанном методе быть точечной нотацией или иметь прямой доступ к переменной? –

+0

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

+0

Я предполагаю, что это происходит в шаблоне, где мне нужно что-то перезагрузить. Я загружаю его в инициализатор, а затем, если пользователь делает покупки в приложении, вам нужно перезагрузить его снова. –

2

Вы никогда не использовали бы self.someString = anything в своем инициализаторе. Точечная нотация - вызов метода. Вы не должны вызывать методы классов, которые еще не полностью созданы. Наиболее очевидный случай сбоя: подкласс переопределяет setSomeString: - где он находится в его init, когда этот метод называется?

ARC будет обрабатывать надлежащее сохранение и освобождение от переменных экземпляра, но не может автоматически делать копии - например, есть __strong и __weak модификаторы, но нет __copy. Поэтому вам все равно нужно явно копировать при выполнении прямого назначения переменной экземпляра.

+0

Спасибо за ответ. Я никогда не переоцениваю методы свойств, поэтому я и делаю это. Иногда я сталкиваюсь с тем, что мне приходится вызывать метод из инициализатора, который обращается к свойствам, и я также должен вызывать тот же самый метод из кода где-то. Как вы справляетесь с этой ситуацией? Должны ли свойства в указанном методе быть точечной нотацией или иметь прямой доступ к переменной? –

+0

Проблема заключается в том, что даже если вы лично не переопределяете атрибуторы свойств, запись вашего кода, чтобы не допускать их переопределения, вводит ограничения, которые не могут быть адекватно выражены в интерфейсе или в другом месте. Так что это считается плохой практикой. Вызов последовательных методов может ссылаться на одни и те же проблемы, поэтому он формально проблематичен. – Tommy

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