#cocoa #properties #private #instance-variables
#cocoa #свойства #Частное #переменные экземпляра
Вопрос:
Я хотел бы знать, каковы рекомендации по объявлению частных переменных экземпляра в cocoa. Этот вопрос относится к контексту разработки приложений для iPhone.
Мне известно как минимум о трех способах объявления частных переменных:
-
Объявите их в интерфейсе файла h с модификатором @private:
@interface MyClass : NSObject { @private NSObject * myPrivateVar; }
-
Объявите их в разделе реализации файла m:
@implementation MyClass NSObject * myPrivateVar;
-
Объявите свойство в интерфейсе m-файла (даже не объявляя саму переменную):
@interface MyClass () @property (nonatomic, retain) NSString* myPrivateVar; @end @implementation @synthesize myPrivateVar;
До сих пор я широко использовал 2, но недавно понял, что это может быть опасно из-за отсутствия сборки мусора. Существуют ли случаи, когда использование этого метода остается вполне приемлемым?
Является ли 3 более подходящим? Зависит ли ответ от типа объекта (например, изменяемый / неизменяемый)?
Также приветствуются указатели на справочный материал, в котором обсуждаются компромиссы при использовании / неиспользовании свойств в целом.
Комментарии:
1. На iPhone нет сборки мусора.
2. Поскольку вы написали это, также возможно объявить iVar в реализации, таким образом:
@implementation MyClass { NSObject * myPrivateVar; }
Ответ №1:
Ваши три варианта имеют разную семантику:
- Это создает переменную экземпляра. Без сборки мусора вам нужны
retain
/release
объекты, в которые вы сохраняетеmyPrivateVar
. - Это вообще не определяет переменную экземпляра. Переменные, определенные за пределами
@interface
и области видимости многих определений методов (или функций), являются «глобальными» — фактически переменными класса (для которых Objective-C не имеет специального синтаксиса). Такая переменная является общей для всех экземпляровMyClass
. - Разница между использованием свойства (с явно объявленной переменной или без нее) сводится к управлению памятью. Определение, которое у вас есть с помощью
retain
, означает, что нет необходимости вretain
/release
, когда у вас нет сборки мусора.
Поэтому не используйте 2! Вариант 3 явно имеет преимущества, если у вас нет сборки мусора, он обеспечивает некоторую степень абстракции по сравнению с вариантом 1 и является более дорогостоящим — хотя вы, вероятно, не заметите разницы за пределами интенсивного с точки зрения вычислений кода, который интенсивно обращается к переменной.
Обновление 2015
Там, где над ARC используется сборка мусора (автоматический подсчет ссылок), теперь более применимо (сборка мусора теперь устарела). Также теперь есть четвертый вариант:
-
Объявите их в разделе реализации файла m:
@implementation MyClass { NSObject * myPrivateVar; }
В отличие от варианта (2), здесь объявляется переменная экземпляра. Переменная является частной для реализации, а с ARC управление памятью происходит автоматически. Выбор между this и (3) [который, кстати, также больше не требует
@synthesize
] сводится к выбору и необходимости; свойства предоставляют вам синтаксис dot, возможность настраивать установщик и / или получатель иcopy
атрибут для автоматического копирования при назначении, но если вам не нужно ничего из этого, вы можете просто использовать переменную экземпляра.
Комментарии:
1. Спасибо. Я был так удивлен, что в варианте 2 объявлялось статическое значение, что написал небольшой тест, чтобы убедить себя. Действительно, вы были правы. Я мало что знал. Вариант 3 кажется действительно лучшим подходом для частных переменных, которые не обязательно должны быть статическими.