2012-01-25 3 views
7

У меня есть приложение, которое я пишу, который использует исключительно @properties. У меня нет ни одного ivar, объявленного вообще ни в одном из моих файлов классов. Насколько я понимаю, ivars больше не нужны с введением @property. Я кодирую в соответствии с лучшей практикой? Это в конечном итоге кусает меня в пресловутом прикладе в долгосрочной перспективе? Я читал смешанные обзоры о том, что является «правильным» и «неправильным» ...Должен ли я использовать ivars в Objective-C?

+0

Обратите внимание, что если у вас есть как объявление ivar, так и объявление свойства для того же ivar, ваш код не является сухим (не повторяйте себя). –

+0

Ответ на этот вопрос зависит, помимо прочего, от того, когда вы задали вопрос. «Идеальный» подход здесь был движущей целью. –

ответ

11

Обычно я не объявляю иваров. Я часто использую @synthesize foo = foo_;, хотя для предотвращения прямого доступа, когда я имел в виду сквозной метод или наоборот. И я всегда позволяю компилятору автоматически синтезировать ivar с префиксом _ (что предотвращает случайный прямой доступ, в соответствии с фраза ).

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

Я также считаю, что шумиха над «использует только прямой доступ в init/dealloc, используйте setter/getter везде», чтобы быть в значительной степени раздутым и, таким образом, просто использовать сеттер/приемник повсюду. Реальность заключается в том, что если у вас есть наблюдатели во время инициализации/освобождения, вы уже были заняты; состояние объекта по определению не определено во время строительства/разрушения и, таким образом, наблюдатель не может правильно рассуждать о государстве.


В Калеб указывает, еще одна причина, чтобы использовать прямой доступ ИВАР в INIT/dealloc, чтобы избежать подклассы, которые реализуют пользовательские сеттер/геттер логику, которая может Barf из-за неопределенного состояния объекта во время инициализации/dealloc.

Хотя это может быть правдой, я считаю это неприятным архитектурным недостатком для реализации сеттеров/геттеров с пользовательским поведением. Это неустойчиво и значительно затрудняет реорганизацию кода с течением времени. Кроме того, такое обычное поведение часто будет зависеть от другого состояния внутри объекта, и эта зависимость затем приводит к зависимостям заказов от изменений состояния, которые отнюдь не отражены в кажущейся простой декларации @property.

I.e. если ваши сеттеры и геттеры написаны таким образом, что foo.bar = bad; не может быть выполнен по номеру любой раз на foo, тогда ваш код будет заблокирован.

+1

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

+0

@ohhorob Где они заявляют это? Дело не в том, что я не согласен - я всегда думал, что это так. Но я несколько раз искал заявление об этом в документах несколько раз и пришел пустым. Если вы знаете, где это, пожалуйста, поделитесь! – Caleb

+0

@Emile - Ahhh! Это здорово знать. Я всегда задавался вопросом, почему в некоторых приложениях я вижу значения в отладчике, а иногда и нет. Возможно, это связано с тем, объявлен ли ivar или нет. Я должен немедленно это расследовать! =) – ElasticThoughts

2

Использование iVars, конечно, не является неправильным, однако лучшие практики теперь нажимают вместо использования @property.

15

Это не так, что переменные экземпляра не нужны. Это просто переменная экземпляра объявлений не нужны. Учитывая свойство и оператор @synthesize, компилятор позаботится о создании переменной экземпляра вместе с соответствующими методами доступа.

Нет ничего плохого в использовании свойств исключительно. Они упрощают управление памятью. Также нет ничего плохого в использовании iVars без свойств, если это то, что вы хотите. Если вы хотите использовать свойства, но не хотите рекламировать аксессоров для остального мира (т. Е. Поддерживать инкапсуляцию), рассмотрите возможность объявления ваших непубличных свойств в расширении класса (в основном анонимной категории в вашем файле реализации).

0

Одно место, где вы можете использовать ivar, - это когда вы хотите объявить защищенное свойство. Вы объявляете свойство в .m-файле для класса и объявляете его соответствующий ivar в .h с помощью директивы @protected.Это позволит вам получить защищенный доступ в подклассе. Для защищенного доступа к членам нет альтернативы.