复习kvc/kvo,然后延伸到swift的didSet/willSet,整理的笔记.2017/08/21 [TOC] ## KVC / KVO 参考资料:[KVO 和 KVC 的使用和实现](https://www.zybuluo.com/MicroCai/note/66738),[KVC 和 KVO](https://www.objccn.io/issue-7-3/) kvc:Key-Value-Coding,用于键值编码; kvo:Key-Value-Observing,顾名思义用于观察键值. 它们被放在Objective-C中NSObject类的Category里实现。 > Swift类使用kvc/kvo必须继承NSObject,它们以extension的形式存在。 kvc提供了四个方法: ```objective-c - (id)valueForKey:(NSString *)key; - (void)setValue:(id)value forKey:(NSString *)key; - (id)valueForKeyPath:(NSString *)keyPath; - (void)setValue:(id)value forKeyPath:(NSString *)keyPath; ``` 通过kvc可以直接访问private属性, swift中不能操作private修饰的属性. 假设Person有address(NSString)、weight(CGFloat)两个private属性,Test类有test1(BOOL)、test1(NSInteger)、test3(NSString)、test4(CGFloat)、test5(Person)五个private属性。那么, ```objective-c Test *t = [[Test alloc]init]; [t setValue:@(YES) forKey:@"test1"]; //给test1赋值 NSLog(@"%@", [t valueForKey:@"test1"]); //获取test1的值 [t setValue:12.12 forKeyPath:@"test5.weight"]; //给test5的weight属性赋值 NSLog(@"%@", [t valueForKeyPath:@"test5.weight"]); //获取test5的weight属性值 ``` kvo提供了一个方法一个协议: ``` //协议(观察者需要实现的协议) - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context //方法 - (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context; ``` addObserver方法中, observer是观察者, keyPath是键值(被观察对象的属性名字), options是一个枚举类型数组, 用来设置需要传递给观察者的信息, context是附加信息. > 注意:在swift中Int Bool Float Double的optional类型的属性不能使用kvc赋值和获取。 ## didSet / willSet didSet/willSet是swift中替代kvo的方法 ```objective-c class test: NSObject { var name: String{ didSet{ print("oldValue==>",oldValue) } willSet{ print("newValue==>",newValue) } } } ``` didSet是属性被修改之后调用的, willSet是属性被修改之前调用. didSet方法作用范围里有一个oldValue的对象, 它存放着该属性在没有修改之前的值. willSet方法作用范围里有一个newValue的对象, 它存放着该属性即将变化的值. 如果需要限制属性的值, 比如name不能为"test", 请见下一篇笔记: set/get
没有评论