KVO原理

原理

调用 [p1 addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew context:NULL];方法后,系统会给当前类A创建一个子类NSKVONotifying_A,通过重写getter和setter方法,完成对属性的监控。

代码参考

- (void)viewDidLoad {
    [super viewDidLoad];

    
    Person *p1 = [[Person alloc] init];
    Person *p2 = [[Person alloc] init];
    
    id cls1 = object_getClass(p1);
    id cls2 = object_getClass(p2);
    NSLog(@"添加 KVO 之前: cls1 = %@  cls2 = %@ ",cls1,cls2);
    
    [p1 addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew context:NULL];
     cls1 = object_getClass(p1);
     cls2 = object_getClass(p2);
    
    
    NSString *methodList1 = [self printPersonMethods:cls1];
    NSString *methodList2 = [self printPersonMethods:cls2];

    NSLog(@"%@",methodList1);
    NSLog(@"%@",methodList2);
}

- (NSString *) printPersonMethods:(id)obj {
    
    unsigned int count = 0;
    Method *methods = class_copyMethodList([obj class],&count);
    NSMutableString *methodList = [NSMutableString string];
    [methodList appendString:@"[\n"];
    for (int i = 0; i<count; i++) {
        Method method = methods[i];
        SEL sel = method_getName(method);
        [methodList appendFormat:@"%@",NSStringFromSelector(sel)];
        [methodList appendString:@"\n"];
    }
    
    [methodList appendFormat:@"]"];
    
    free(methods);
    
    return methodList;
}
  • 使用下面的方法监控参数的变化
func willChangeValue(forKey key: String)
func didChangeValue(forKey key: String)

推荐阅读更多精彩内容