KVO原理及代码

1.KVO分为自动和手动

当+ (BOOL)automaticallyNotifiesObserversForKey:(NSString*)key为YES的时候自动观察,可以观察到属性的变化

当为NO的话在set方法前后willChangeValueForKey   didChangeValueForKey既可以观察到属性的变化


2.当观察数组的元素变化的时候,不可以直接观察,可以使用kvc进行观察

NSMutableArray *arr = [self.personPeople mutableArrayValueForKey:@"arr"];

  [arraddObject:@"123"];

3.当观察一个类对象的时候,可以分别观察类对象.属性:

 [paddObserver:self forKeyPath:@"dogg.age" options:(NSKeyValueObservingOptionNew) context:nil];

也可以使用这个方法来

+(NSSet *)keyPathsForValuesAffectingValueForKey:(NSString*)key

{

    NSLog(@"%@",key);

    NSSet *keyPaths = [super keyPathsForValuesAffectingValueForKey:key];

    if([keyisEqualToString:@"dogg"]) {

        NSArray *arr = @[@"_dogg.age",@"_dogg.ageee"];

        keyPaths = [keyPathssetByAddingObjectsFromArray:arr];


    }

    returnkeyPaths;

}

此时观察的时候:

 [paddObserver:self forKeyPath:@"dogg" options:(NSKeyValueObservingOptionNew) context:nil];即可观察到dogg的age和ageee的属性变化

4.根据KVO的原理,动态创建被观察类的子类,并添加set方法(其实创建子类并不意味着我们就有了该属性的set方法,否者也不会出现通过继承关系找类的实现),在改变前后告诉被观察者属性的改变,并通过isa指针指向元类

此时我们可以自己写kvc的观察

- (void)MT_addObserver:(NSObject*)observer forKeyPath:(NSString*)keyPath options:(NSKeyValueObservingOptions)options context:(void*)context{

    //1.判断kayPath是否存在

    SELsetterSeletor =NSSelectorFromString([NSStringstringWithFormat:@"set%@:",keyPath.capitalizedString]);

    ClasssuperClass =object_getClass(self.class);

    //2.自定义一个被观察类的子类

    NSString*oldClassName =NSStringFromClass(self.class);

    NSString*newClassName = [NSStringstringWithFormat:@"MTKVO_%@",oldClassName];

    //创建一个类

     ClassnewClass =objc_allocateClassPair(self.class, newClassName.UTF8String,0);

    //注册该类

    objc_registerClassPair(newClass);

    //2.动态修改该类和被观察类绑定

    object_setClass(self, newClass);


    //3.添加setName方法,此时一定要对应setName这样类似的方法,IMP是函数指针找到对应的函数,“V”表示void,@表示oc参数

    class_addMethod(newClass, setterSeletor, (IMP)haha,"v@:@");


}

//oc方法中有2个隐藏参数:id self,SEL _cmd,此时应该添加上,否者打印不出对应属性

voidhaha(idself,SEL_cmd,NSString*newName){

    NSLog(@"%@",newName);

}

demo地址:GitHub - 969661780/KVO: KVO原理

你可能感兴趣的:(KVO原理及代码)