Будет ли компилятор автоматически синтезировать ивар для свойства, объявленного в категории?

До так называемого "Современного Objective-C" при создании нового свойства в категории нам нужно было реализовать методы setter и getter. Теперь нам не нужно делать @synthesize; Компилятор автоматически создаст методы и переменную экземпляра.

Но обычно мы не можем добавлять переменные экземпляра в категорию, так что произойдет, если мы добавим новое свойство в категорию с современным Objective-C? Компилятор создает для нас ивар?

3 ответа

Вы можете объявить свойство в категории, что эквивалентно объявлению селекторов get и (если readwrite).

Компилятор не будет автоматически синтезировать методы получения и установки в реализации вашей категории. Если вы не определите их явно в реализации категории, компилятор выдаст предупреждение. Ты можешь использовать @dynamic в реализации категории для подавления предупреждения. Вы не можете использовать @synthesize в категории реализации; Компилятор выдаст ошибку, если вы попытаетесь.

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

Я проверил свои заявления, используя Xcode 4.5.1 для iOS 6.0.

На самом деле я не знаю, когда мы смогли добавить property в категориях.

Из Apple Docs:

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

а также

Расширения классов похожи на анонимные категории, за исключением того, что методы, которые они объявляют, должны быть реализованы в главном блоке @implementation для соответствующего класса. Используя компилятор Clang/LLVM 2.0, вы также можете объявить свойства и переменные экземпляра в расширении класса.

и этот метод используется для добавления хранилища к объекту без изменения объявления класса (в случае, если вы не можете изменить или не имеете доступа к исходным кодам класса)

Ассоциативные ссылки, доступные начиная с OS X v10.6, имитируют добавление переменных экземпляра объекта в существующий класс. Используя ассоциативные ссылки, вы можете добавить хранилище к объекту без изменения объявления класса. Это может быть полезно, если у вас нет доступа к исходному коду для класса, или если по соображениям бинарной совместимости вы не можете изменить макет объекта.

Так что ваш вопрос для меня кажется неправильным.

Источник: Apple Docs - язык программирования Objective-C

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

Так что в заголовке вашей категории... если все, что вы хотите сделать, это прочитать значение...

@property (только для чтения) NSString *uniqueID;

а затем напишите свой геттер...

- (NSString*) uniqueID { return @"You're not special"; }

Но скажите... вы не можете просто придумать значение из вашего геттера... и вам нужно хранилище либо для внешнего сеттера..., либо для использования собственной реализации класса... вы ДОЛЖНЫ написать такой сеттер, как...

- (void) setUniqueID:(NSString*)uId 

Это не обязательно должно быть публично, обязательно... но именно здесь происходит "волшебство".

 …
[self setAssociatedValue:uId forKey:@"yourInternalStorageName"
                  policy:OBJC_ASSOCIATION_RETAIN_NONATOMIC];

Посмотрев на это, я понял, что использую некоторые "персональные категории", чтобы облегчить настройку, получение и т. Д. Этих значений... поэтому я опубликовал их в этой сути, поскольку они ОЧЕНЬ полезны... и включают такие маленькие жемчужины как...

- (id) associatedValueForKey:(NSString*)key 
                     orSetTo:(id)anObject 
                      policy:(objc_AssociationPolicy) policy;

Секрет "получения" - это часть "политики".. Эти ценности...

OBJC_ASSOCIATION_ASSIGN = 0,
OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1,
OBJC_ASSOCIATION_COPY_NONATOMIC = 3,
OBJC_ASSOCIATION_RETAIN = 01401,
OBJC_ASSOCIATION_COPY = 01403

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

Другие вопросы по тегам