Лучший способ объявления частных переменных в cocoa

#cocoa #properties #private #instance-variables

#cocoa #свойства #Частное #переменные экземпляра

Вопрос:

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

Мне известно как минимум о трех способах объявления частных переменных:

  1. Объявите их в интерфейсе файла h с модификатором @private:

     @interface MyClass : NSObject {  
      @private  
      NSObject * myPrivateVar;   
    }
      
  2. Объявите их в разделе реализации файла m:

     @implementation MyClass  
    NSObject * myPrivateVar;
      
  3. Объявите свойство в интерфейсе m-файла (даже не объявляя саму переменную):

     @interface MyClass ()  
    @property (nonatomic, retain) NSString* myPrivateVar;  
    @end  
    @implementation  
    @synthesize myPrivateVar;
      

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

Является ли 3 более подходящим? Зависит ли ответ от типа объекта (например, изменяемый / неизменяемый)?

Также приветствуются указатели на справочный материал, в котором обсуждаются компромиссы при использовании / неиспользовании свойств в целом.

Комментарии:

1. На iPhone нет сборки мусора.

2. Поскольку вы написали это, также возможно объявить iVar в реализации, таким образом: @implementation MyClass { NSObject * myPrivateVar; }

Ответ №1:

Ваши три варианта имеют разную семантику:

  1. Это создает переменную экземпляра. Без сборки мусора вам нужны retain / release объекты, в которые вы сохраняете myPrivateVar .
  2. Это вообще не определяет переменную экземпляра. Переменные, определенные за пределами @interface и области видимости многих определений методов (или функций), являются «глобальными» — фактически переменными класса (для которых Objective-C не имеет специального синтаксиса). Такая переменная является общей для всех экземпляров MyClass .
  3. Разница между использованием свойства (с явно объявленной переменной или без нее) сводится к управлению памятью. Определение, которое у вас есть с помощью retain , означает, что нет необходимости в retain / release , когда у вас нет сборки мусора.

Поэтому не используйте 2! Вариант 3 явно имеет преимущества, если у вас нет сборки мусора, он обеспечивает некоторую степень абстракции по сравнению с вариантом 1 и является более дорогостоящим — хотя вы, вероятно, не заметите разницы за пределами интенсивного с точки зрения вычислений кода, который интенсивно обращается к переменной.

Обновление 2015

Там, где над ARC используется сборка мусора (автоматический подсчет ссылок), теперь более применимо (сборка мусора теперь устарела). Также теперь есть четвертый вариант:

  1. Объявите их в разделе реализации файла m:

     @implementation MyClass  
    {
       NSObject * myPrivateVar;
    }
      

    В отличие от варианта (2), здесь объявляется переменная экземпляра. Переменная является частной для реализации, а с ARC управление памятью происходит автоматически. Выбор между this и (3) [который, кстати, также больше не требует @synthesize ] сводится к выбору и необходимости; свойства предоставляют вам синтаксис dot, возможность настраивать установщик и / или получатель и copy атрибут для автоматического копирования при назначении, но если вам не нужно ничего из этого, вы можете просто использовать переменную экземпляра.

Комментарии:

1. Спасибо. Я был так удивлен, что в варианте 2 объявлялось статическое значение, что написал небольшой тест, чтобы убедить себя. Действительно, вы были правы. Я мало что знал. Вариант 3 кажется действительно лучшим подходом для частных переменных, которые не обязательно должны быть статическими.