手动实现KVO

作者: Mr吴标 | 来源:发表于2016-05-24 09:04 被阅读161次

步骤:
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

相关文章

  • iOS面试题0004-KVC和KVO的keyPath一定是属性么

    KVC 支持实例变量,KVO 只能手动支持手动设定实例变量的KVO实现监听

  • iOS面试题(4) KVO KVC

    声明,不是原创,笔记均来自 群主大神~ 手动实现KVO 什么是KVO和KVC? KVO内部实现原理 NSNotif...

  • Key-Value-Observing OC&Swift

    KVC 支持实例变量,KVO 只能手动支持手动设定实例变量的KVO实现监听。KVO通过set方法来通知。或者KVC...

  • 手动实现KVO

    1 首先根据key 生成Set方法 2 检测observer 检测set方法 是否存在 不存在抛出异常 3 根绝当...

  • 手动实现KVO

    前言 之前只是了解KVO的原理,但是从未自己手动实现过KVO,主要是因为之前对runtime的操作函数没有那么熟练...

  • 手动实现KVO

    继承自NSObject的对象都会自动带有KVO,以下手动实现非继承自NSObject类的KVO。 以下翻译自苹果官...

  • 手动实现KVO

    步骤:1.生成一个Person类的子类 NSKVONotifying_Person2.使当前对象的isa指向新的类...

  • KVO和手动调用KVO

    参考链接: http://tech.glowing.com/cn/implement-kvo/ 手动实现KVO 1...

  • iOS KVO的手动实现过程

    如何手动触发一个value的KVO 手动实现 willChangeValueForKey 和 didChangeV...

  • iOS高级进阶之KVO

    KVO的原理 分析原理 使用 手动调用 自己实现KVO NSObject+KVOBlock.h NSObject+...

网友评论

    本文标题:手动实现KVO

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