响应式编程思想——>KVO底层实现揭秘

最近在学习ReactCocoa,学习前,首先需要了解的几种编程思想,包括面向对象,面向过程,链式编程,响应式编程,函数式编程思想等,这里主要介绍一下响应式编程,其他的几种会一一介绍。

`响应式编程思想`:不需要考虑调用顺序,只需要知道考虑结果,类似于蝴蝶效应,产生一个事件,会影响很多东西,这些事件像流一样的传播出去,然后影响结果,借用面向对象的一句话,万物皆是流。

了解了上面的概念,可能还是不是很清楚,下面举例说明一下,最典型的就是我们开发过程中常见的KVO,下面详细讲解一下KVO的底层实现:

首先,当为一个对象添加一个观察者,即调用 [p addObserver:self forKeyPath:@"age" options:NSKeyValueObservingOptionNew context:nil]这个方法的时候,其实OC的底层会做一下操作

 1.只要page属性一改变,就会调用观察者的observeValueForKeyPath

 KVO底层实现:

 1.动态创建NSKVONotifying_Person,NSKVONotifying_PersonPerson子类,KVO

 2.修改当前对象的isa指针->NSKVONotifying_Person

 3.只要调用对象的set,就会调用NSKVONotifying_Personset方法

4.重写NSKVONotifying_Personset方法,(1).[super set:] (2).通知观察者,告诉你属性改变

其实,底层实现的实质就是去判断有没有调用一个对象的set方法,如果你改变一个对象的属性的值,不通过set方法,那么KVO就会失效,就不会观察到。

自己仿造苹果的KVO实现代码如下:

1.为NSObject添加一个分类

#import <Foundation/Foundation.h>

@interface NSObject (KVO)

- (void)xmg_addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(nullable void *)context;


@end
#import "NSObject+KVO.h"

#import "XMGKVONotifying_Person.h"


#import <objc/runtime.h>

@implementation NSObject (KVO)
- (void)xmg_addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context
{
    // 1.动态创建NSKVONotifying_Person,NSKVONotifying_Person是Person子类,做KVO
    // 2.修改当前对象的isa指针->NSKVONotifying_Person
    // 3.只要调用对象的set,就会调用NSKVONotifying_Person的set方法
    // 4.重写NSKVONotifying_Person的set方法,1.[super set:] 2.通知观察者,告诉你属性改变
    
    // 修改isa,本质就是改变当前对象的类名
    object_setClass(self, [XMGKVONotifying_Person class]);
    
    // 把观察者保存到当前对象里
    
    
    // 添加关联
    // id object:给哪个对象添加关联属性
    // key:属性名
    // value:关联值
    objc_setAssociatedObject(self, @"observer", observer, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    
}
@end

2.创建一个Person的子类--> XMGKVONotifying_Person,并且重写  XMGKVONotifying_Person的setAge方法,即可
#import "Person.h"

@interface XMGKVONotifying_Person : Person

@end

#import "XMGKVONotifying_Person.h"

#import <objc/runtime.h>

@implementation XMGKVONotifying_Person

- (void)setAge:(int)age
{
    [super setAge:age];
    
    // 通知观察者,属性改变
    id observer = objc_getAssociatedObject(self, @"observer");
    
    [observer observeValueForKeyPath:@"age" ofObject:self change:nil context:nil];
}

@end
,至此,就用自己的一套替代了苹果底层的KVO的实现,同样的效果。

其中在为NSObject添加的分类的过程中,用到了一些运行时的东西,也就是在给NSObject动态的添加一个属性observe来保存观察者的时候,运行时真的是一个很牛逼的东西,很多东西需要潜心的去探索,这里重点不在运行时,后续会有专门的文章来叙述。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值