美文网首页
利用runtime自己动手实现KVO- 简书

利用runtime自己动手实现KVO- 简书

作者: 幻梦_ | 来源:发表于2017-10-20 15:08 被阅读0次

昨天开始学习runtime写下做个记录,利用runtime实现系统的KVO,首先我们先来看一下系统的实现,首先定义Persion类添加一个name的属性,在ViewController类中初始化并添加一个kvo监听Persion类中name属性的变化

从控制台可以看出p对象的isa指向了一个NSKVONotifying_Persion的一个类.所以我们用runtime动态创建一个类重写其中的setName方法,在setName的方法中得到改变的值通过objc_msgSend()方法发送到viewController控制器中。

*注 xcode 9 objc_msgSend()传递多个参数需要把Enable Strict Checking of objc_msgSend Calls 设置为NO

下面主要利用runtime实现KVO主要代码实现

新建一个NSObject的Category

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

//得到当前类名称

NSString*oldClassName =NSStringFromClass([selfclass]);

//自定义类名

NSString*NewClassName = [@"ZH_"stringByAppendingString:oldClassName];

//转换为c语言语法

constchar* newName = [NewClassNameUTF8String];

ClassMyclass =objc_allocateClassPair([selfclass], newName,0);

//重写setAge方法!!

class_addMethod(Myclass,@selector(setName:), (IMP)setName,"v@:@");

//注册这个类

objc_registerClassPair(Myclass);

//修改被观察者的isa指针!!让它指向自定义的类!!

object_setClass(self, Myclass);

//使用key绑定observer 以供下面发送通知使用

objc_setAssociatedObject(self,@"111", observer,OBJC_ASSOCIATION_RETAIN_NONATOMIC);

}

void setName(idself,SEL_cmd,idname){

//保存当前类型

ClassfClass = [selfclass];

//改变当前对象指向父类!!

object_setClass(self,class_getSuperclass([selfclass]));

//调用父类的setName方法

objc_msgSend(self,@selector(setName:),name);

//拿出观察者

idobserver =objc_getAssociatedObject(self,@"111");

//通知外界

objc_msgSend(observer,@selector(observeValueForKeyPath:ofObject:change:context:),self,@"name",@{@"new":name},nil);

object_setClass(self, fClass);

}

利用业余时间记录一下,如有错误欢迎指正,有兴趣的朋友可以互相交流,希望大家共同进步。

相关文章

网友评论

      本文标题:利用runtime自己动手实现KVO- 简书

      本文链接:https://www.haomeiwen.com/subject/apcvuxtx.html