细说KVO

  • Post author:
  • Post category:其他


1.手动控制kvo的触发
+ (BOOL)automaticallyNotifiesObserversForKey:(NSString *)key; 返回NO ;

然后在改变value前 调用[object willChangeValueForKey:@"key"];
在改变value后, 调用[object didChangeValueForKey:@"key"] ;

2.隔层kvo观察

@interface Dog : NSObject

@property(nonatomic)NSInteger age;

@property(nonatomic)NSInteger *level;

@end

#import <Foundation/Foundation.h>

#import “Dog.h”

@interface Person : NSObject

@property(nonatomic,strong)Dog *dog;

@end

#import “Person.h”

@implementation Person

-(instancetype)init{

self = [super init];

if (self) {

_dog = [[Dog alloc]init];

}

return self;

}

+(NSSet<NSString *> *)keyPathsForValuesAffectingValueForKey:(NSString *)key{

NSSet *keyPath = [super keyPathsForValuesAffectingValueForKey:key];

if ([key isEqualToString:@”dog”]) {

NSArray *arr = @[@”_dog.level”,@”_dog.age”];

keyPath = [keyPath setByAddingObjectsFromArray:arr];

}

return keyPath;

}

@end


//设置观察

self.person = [[Person alloc] init];

[self.person addObserver:self forKeyPath:@”dog” options:NSKeyValueObservingOptionOld context:nil];

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context

{

NSLog(@”change:%@”,change);

}

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event  {

self.person.dog.age++;

}


2.KVO的底层实现

#import “NSObject+PRKVO.h”

#import <objc/runtime.h>

@implementation NSObject (PRKVO)

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

{

//1.自定义一个NSKVONotifying_Person子类

NSString *oldClassName = NSStringFromClass(self.class);

NSString *newClassName = [@”PRKVO_” stringByAppendingString:oldClassName];

//创建一个类

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

//注册该类

objc_registerProtocol(MyClass);

//2.动态修改

object_setClass(self, MyClass);

//3.添加setName方法,重新父类setName

class_addMethod(MyClass, @selector(setName:), (IMP)haha, “v@:@”);

}

void haha(id self,SEL _cmd,NSString *newName){

NSLog(@”!%@”,newName);

}

 



转载于:https://www.cnblogs.com/PJXWang/p/8431666.html