Ответ 1
В следующем эксперименте делается вывод о том, что свойство собственного текста задано до свойства категории, поэтому значение можно безопасно перезаписать установщиком категории.
Категория ярлыков:
// UILabel+Thingy.h
#import <UIKit/UIKit.h>
@interface UILabel (Thingy)
@property (nonatomic, strong) IBInspectable NSString *thingy;
@end
// UILabel+UILabel_Thingy.m
#import "UILabel+Thingy.h"
#import <objc/runtime.h>
@implementation UILabel (Thingy)
- (NSString *)thingy {
return objc_getAssociatedObject(self, @selector(thingy));
}
- (void)setThingy:(NSString *)thingy {
NSLog(@"setting thingy to '%@', my text is currently '%@'", thingy, self.text);
objc_setAssociatedObject(self, @selector(thingy), thingy, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
@end
В IB установите свойство проверяемой категории и свойство текста....
Небольшая аппаратура в контроллере с открытым представлением:
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"didLoad text is '%@' and thingy is '%@'", self.label.text, self.label.thingy);
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
NSLog(@"willAppear text is '%@' and thingy is '%@'", self.label.text, self.label.thingy);
}
Запустите его, а выход NSLog указывает, что во время пробуждения от nib собственное свойство устанавливается к тому времени, когда вызывается свойство setter...
... [794: 41622], устанавливая thingy на "thingy value", мой текст в настоящее время "текстовое значение"
... [794: 41622] didload text - это "текстовое значение" , а thingy - значение "thingy"
... [794: 41622] willappear text - это "текстовое значение" , а thingy - "вещь"
Настройка свойства текста метки в элементе настройки свойства категории (и, я проверял его) приводит к тому, что свойство text будет перезаписано в свойство thingy, так как сначала свойство initialize инициализируется.
Другие доказательства можно увидеть в файле XIB при визуализации в виде XML...
<label opaque="NO" (... all the native properties) text="text value" (...) id="XAM-6h-4fn">
<rect key="frame" x="274" y="147" width="278" height="34"/>
(... and so on)
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="thingy" value="thingy value"/>
</userDefinedRuntimeAttributes>
</label>
..., который согласуется с тем, как создается экземпляр и инициализируется через предварительный обход, тем самым устанавливая свойства метки (родительского тега) перед (дочерним тегом) userDefinedRuntimeAttributes.