以下实验得出结论,原生文本属性设置在类别属性之前,因此该值可以安全地被类别设置器覆盖。
一个标签类别:
// 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 唤醒期间,本地属性在调用类别属性设置器时设置...
...[794:41622] 将thingy 设置为'thingy value',我的文本当前是'text value'
...[794:41622] didload text 是 'text value' 而 thingy 是 'thingy value'
...[794:41622] 会出现 text is 'text value' 而 thingy 是 'thingy value'
在类别属性设置器中设置标签的 text 属性将(并且确实,我测试过)导致 text 属性被覆盖到 thingy 属性,因为 text 属性首先被初始化。
当呈现为 XML 时,可以在 XIB 文件中看到更多证据...
<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>
... 这与通过 pre-order 遍历被实例化和初始化的视图一致,从而在(子标签)userDefinedRuntimeAttributes 之前设置(父标签)标签属性。