KVC、KVO

2019-02-24  本文已影响1人  liboxiang

https://juejin.im/post/5aef18b76fb9a07aa34a28e6
https://objccn.io/issue-7-3/

KVC

https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/KeyValueCoding/BasicPrinciples.html#//apple_ref/doc/uid/20002170-BAJEAIEE
KVC的灵活运用上归结为可以通过字符串(key)获取值

KVC使用
#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        
        NSArray* arrStr = @[@"english",@"franch",@"chinese"];
        NSArray* arrCapStr = [arrStr valueForKey:@"capitalizedString"];
        for (NSString* str  in arrCapStr) {
            NSLog(@"%@",str);
        }
        NSArray* arrCapStrLength = [arrStr valueForKeyPath:@"capitalizedString.length"];
        for (NSNumber* length  in arrCapStrLength) {
            NSLog(@"%ld",(long)length.integerValue);
        }
        
    }
    return 0;
}
打印结果:
2018-05-05 17:16:21.975983+0800 KVCKVO[35824:6395514] English
2018-05-05 17:16:21.976296+0800 KVCKVO[35824:6395514] Franch
2018-05-05 17:16:21.976312+0800 KVCKVO[35824:6395514] Chinese
2018-05-05 17:16:21.976508+0800 KVCKVO[35824:6395514] 7
2018-05-05 17:16:21.976533+0800 KVCKVO[35824:6395514] 6
2018-05-05 17:16:21.976550+0800 KVCKVO[35824:6395514] 7
获取属性值
设置属性值
访问集合属性
集合运算符

当你对一个对象(集合/数组)发送了valueForKeyPath:消息的时候,集合操作允许你通过嵌入关键字的形式作出相应的操作. 集合操作符是一个以@开头的特殊字符串. for example: @distinctUnionOfObjects.self 无论什么时候你在key path中看见了@,它都代表了一个特定的集合方法,其结果可以被返回或者链接.

image
聚合运算符

以某种方式合并集合的对象

数组运算符
嵌套集合运算符(array中包含array,set中包含set)

KVO

https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/KeyValueObserving/KeyValueObserving.html#//apple_ref/doc/uid/10000177-BCICJDHA
KVO 是通过 isa-swizzling 实现的。 基本的流程就是编译器自动为被观察对象创造一个派生类,并将被观察对象的isa 指向这个派生类。如果用户注册了对某此目标对象的某一个属性的观察,那么此派生类会重写这个方法,并在其中添加进行通知的代码。

KVO的实现,是对注册的keyPath中自动实现了两个函数,在setter中,自动调用。

- (void)willChangeValueForKey:(NSString *)key
- (void)didChangeValueForKey:(NSString *)key
手动KVO(禁用KVO)

首先,需要手动实现属性的 setter 方法,并在设置操作的前后分别调用 willChangeValueForKey: 和 didChangeValueForKey方法,这两个方法用于通知系统该 key 的属性值即将和已经变更了;
其次,要实现类方法 automaticallyNotifiesObserversForKey,并在其中设置对该 key 不自动发送通知(返回 NO 即可)。这里要注意,对其它非手动实现的 key,要转交给 super 来处理。
如果需要禁用该类KVO的话直接automaticallyNotifiesObserversForKey返回NO,实现属性的 setter 方法,不进行调用willChangeValueForKey: 和 didChangeValueForKey方法。

依赖键
@interface LabColor : NSObject

@property (nonatomic, assign) double redComponent;
@property (nonatomic, assign) double greenComponent;
@property (nonatomic, assign) double blueComponent;

@property (nonatomic, strong, readonly) UIColor *color;

@end
@implementation LabColor
+ (NSSet<NSString *> *)keyPathsForValuesAffectingColor {
    return [NSSet setWithObjects:@"redComponent", @"greenComponent", @"blueComponent", nil];
}
@end
//KVO监听color的时候,redComponent, greenComponent, blueComponent有修改也会触发KVO回调
上一篇 下一篇

猜你喜欢

热点阅读