手动实现KVO

步骤:
1.生成一个Person类的子类 NSKVONotifying_Person
2.使当前对象的isa指向新的类,就会调用新类的set方法
3.重写NSKVONotifying_Person的setAge方法,每次调用,就调用观察者的observeValueForKeyPath方法
4.如何在set方法中,拿到观察者,使用运行时让当前对象关联观察者这个属性。

#import "ViewController.h"
#import "Person.h"
#import "NSObject+KVO.h"

@interface ViewController ()
@property (nonatomic, strong) Person *person;
@end
@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    Person *p = [[Person alloc] init];
    
    p.age = 0;
    
    _person = p;
    
    [p wb_addObserver:self forKeyPath:@"age" options:NSKeyValueObservingOptionNew context:nil];
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context
{
    NSLog(@"person的值改变了:%d",_person.age);
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    _person.age = 10;
}

@end

#import "WBKVONotifying_Person.h"

#import <objc/runtime.h>

@implementation WBKVONotifying_Person

- (void)setAge:(int)age
{
    [super setAge:age];
    
    // 调用KVO
    // 获取观察者
    id observer =  objc_getAssociatedObject(self, @"observer");
    
    // 调用观察者的方法
    [observer observeValueForKeyPath:@"age" ofObject:observer change:nil context:nil];
    
}

@end
#import <Foundation/Foundation.h>
@interface NSObject (KVO)
- (void)wb_addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(nullable void *)context;
@end


#import "NSObject+KVO.h"
#import <objc/runtime.h>
#import "WBKVONotifying_Person.h"

@implementation NSObject (KVO)

- (void)wb_addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context
{
    
    // 修改isa指针,就是把当前对象指向一个新类
    object_setClass(self, [WBKVONotifying_Person class]);
    
    // 给对象绑定观测者对象
    objc_setAssociatedObject(self, @"observer", observer, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

@end
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 前言 KVO:简单的来说,就是观察者观察被观察对象属性的变化而发生相应的变化。实现的原理基于KVC与强大的Runt...
    Colleny_Z阅读 1,291评论 0 2
  • 我的Github地址 : Jerry4me, 本文章的demo链接 : JRCustomKVODemo 前言 KV...
    Jerry4me阅读 5,776评论 14 45
  • 文 话忧 他是我男闺蜜,我们相识十几年,彼此欣赏,但是止步于友谊。或许我们对对方都曾有过爱慕之意,但都不曾开口。如...
    话忧阅读 401评论 0 0
  • 2017-3-25【今日晨读】 过程重要结果也重要,有了努力的过程才有结果;有了结果才有方向。是的,在我们的人生路...
    剽悍文霞阅读 206评论 4 3