Как Apple управляет @private var и @properties?

#objective-c

#objective-c

Вопрос:

Я беру для примера UIButton интерфейс.

Вот первые строки @private определения :

   @private
    CFMutableDictionaryRef _contentLookup;
    UIEdgeInsets           _contentEdgeInsets;
    UIEdgeInsets           _titleEdgeInsets;
  

И вот 2 из этих ivar, которые определены как свойства:

 @property(nonatomic) UIEdgeInsets contentEdgeInsets; 
@property(nonatomic) UIEdgeInsetstitleEdgeInsets;
  

Однако эти 2 свойства не определены в ivar, которые я нашел в private method (которые имеют суффикс _ ).

Я не уверен, что понимаю, как можно было бы реализовать setter и getter для этих 2 свойств, чтобы ссылаться на частные переменные.

И второй вопрос … раньше я создавал свойства для ivar, поэтому, если у меня есть ivar FOO , я могу создать @property для FOO . Это нормальное поведение, создающее свойство для несуществующего ivar? (в данном случае contentEdgeInsets не является атрибутом для этого класса … напротив, _contentEdgeInset определен в @interface , и это допустимый ivar). Хорошо, что я пропустил в этом аргументе?

Ответ №1:

Когда вы @синтезируете эти свойства, вам так нравится

 @synthesize contentEdgeInsets = _contentEdgeInsets;
            ^property name      ^iVar name
  

Ознакомьтесь с разделом Директивы по реализации свойств в документации.

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

1. Боже… я идиот: P я никогда не использовал эти опции и забываю думать об этом … но зачем определять это как частное .. и разрешать публичный доступ. Это звучит странно.

2. Нет, ты не идиот :). Общедоступный доступ осуществляется через свойство и обеспечивает инкапсуляцию для класса. Они могли бы однажды, например, избавиться от iVar make contentEdgeInsets @dynamic, и это никогда не повлияло бы на ваш код, поскольку вы получаете к нему доступ через свойство.

3. Хорошо, тогда подход, аналогичный C , определяет метод доступа для частных атрибутов.

4. Да, вы не обращаетесь напрямую к частной переменной, а вызываете метод. view.contentEdgeInsets == [view contentEdgetInsets] свойства — это просто синтаксический сахар. Помимо определения iVar, который поддерживает свойство, вы также можете определить методы получения и установки.

Ответ №2:

По умолчанию свойство будет использовать ivar, имя которого совпадает с именем свойства, но также возможно указать ivar с другим именем. Сделайте это в своем операторе @synthesize в реализации класса.

В современной среде выполнения, используемой на данный момент практически повсеместно, вам вообще не нужно объявлять ivar — если вы синтезируете средства доступа для свойства и нет соответствующего ivar, среда выполнения предоставит его.

Наконец, свойствам с аксессорами @dynamic, а не @synthesized вообще не обязательно нужен ivar — в этом случае вы предоставляете аксессоры, так что вы вольны выводить значение свойства так, как вам нравится.