Пометка переменных экземпляра @private

Я заметил, что многие интерфейсы Apple используют @private перед объявлениями переменных экземпляра. Есть ли для этого веская конструктивная причина, и нужно ли это делать?


person Jonathan Sterling    schedule 19.12.2009    source источник


Ответы (3)


Частные переменные экземпляра используются для отделения интерфейса от реализации. В Objective-C, поскольку объявление класса должно отображать все переменные экземпляра, должен быть способ предотвратить доступ подклассов к тем, которые являются частью внутренней реализации. В противном случае другие программисты могли бы написать код, зависящий от этих внутренних переменных, что сделало бы невозможным для разработчика класса внесение изменений во внутренние элементы класса без нарушения существующего кода.

С другой стороны, переменные экземпляра, которые не помечены как закрытые, являются частью контракта с программистом подкласса, тогда как те, которые помечены как частные, таковыми не являются.

Это означает, что переменные экземпляра обычно должны быть помечены как закрытые, чтобы к ним можно было получить доступ только через их методы доступа, если вообще. В противном случае кто-то может легко написать подкласс вашего класса и просто создать метод доступа, чтобы сделать любую переменную экземпляра общедоступной.

person e.James    schedule 19.12.2009
comment
Спасибо за ваш подробный ответ. Что касается написания подкласса для публикации переменных экземпляра, я почти уверен, что @private не защищает от категорий, публикующих их. Мысли? - person Jonathan Sterling; 19.12.2009
comment
Я пробовал, и вы абсолютно правы. Кажется, что категории имеют доступ ко всем переменным экземпляра, включая частные. Я полагаю, что Objective-C все еще дает вам достаточно веревки, чтобы повеситься, если вы действительно этого хотите :) - person e.James; 19.12.2009
comment
Вы также можете использовать функции времени выполнения для захвата ivar. Но если вы делаете такие вещи, вы знаете, что это грязный взлом, в отличие от невинной зависимости от ивара суперкласса, который вы считали надежным. - person Chuck; 19.12.2009

Если вы не хотите, чтобы подклассы имели доступ к переменным, пометьте их @private.

person Chuck    schedule 19.12.2009

Другой способ сделать это — объявить переменные экземпляра в разделе @implementation. Такие переменные неявно закрыты. Источник: Кочан: Programming in Objective-C, Fourth Edition. п. 199. Таким образом, неверно, что объявление класса должно отображать все переменные экземпляра, как утверждает e.James.

Единственная причина для объявления переменных экземпляра в @interface — разрешить их наследование производным классом (подклассом).

person Graham Asher    schedule 16.01.2012
comment
Правильный способ сделать это в будущем — объявить его в расширении класса в файле .m. Это относится как к частным методам, так и к ivars и свойствам. Расширение класса выглядит как безымянная категория (), но имеет другую семантику и возможности. - person ikuramedia; 17.02.2012