iOS学习笔记

手动实现KVO

2016-05-24  本文已影响161人  Mr吴标

步骤:
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
上一篇 下一篇

猜你喜欢

热点阅读