Будет ли компилятор автоматически синтезировать ивар для свойства, объявленного в категории?
До так называемого "Современного 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, имитируют добавление переменных экземпляра объекта в существующий класс. Используя ассоциативные ссылки, вы можете добавить хранилище к объекту без изменения объявления класса. Это может быть полезно, если у вас нет доступа к исходному коду для класса, или если по соображениям бинарной совместимости вы не можете изменить макет объекта.
Так что ваш вопрос для меня кажется неправильным.
Как уже говорили другие, способ сделать это с помощью ассоциативных ссылок. Они реализованы так же, как 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
захватывать те же черты "личности", которые выражаются при описании ваших свойств в "нормальном" объявлении. Вы должны указать компилятору, как "хранить" ваши значения по тем же правилам, и все будет хорошо.