KVO底层原理分析

2018-07-04  本文已影响0人  iOS扫地僧

一、 KVO内部实现原理

二、论证产生的子类

Book类
#import <Foundation/Foundation.h>

@interface Book : NSObject

@property (nonatomic, copy) NSString *price;

@property (nonatomic, copy) NSString *name;

@end

重写description方法便于观察产生的子类

#import "Book.h"
#import <objc/runtime.h>

@implementation Book

- (NSString *)description {
    NSLog(@"object address : %p \n", self);
    Class objectMethodClass = [self class];
    Class objectRuntimeClass = object_getClass(self);
    Class superClass = class_getSuperclass(objectRuntimeClass);
    NSLog(@"objectMethodClass : %@, ObjectRuntimeClass : %@, superClass : %@ \n", objectMethodClass, objectRuntimeClass, superClass);
    return @"";
}
@end
初始化调用
- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.abook = [[Book alloc]init];
    NSLog(@"初始化%@",self.abook);
    
    [self.abook addObserver:self forKeyPath:@"price" options:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew context:nil];
    [self.abook addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew context:nil];
}
打印结果如下
image.png

注意:这是在绑定观察者模式之前的初始化调用,此时还没有被观察,此时并没有产生子类

触发监听调用
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    NSLog(@"之前%@",self.abook);
    //触发监听
    [self.abook setValue:@"book" forKey:@"name"];
    [self.abook setValue:@"34" forKey:@"price"];
}
打印结果如下
image.png

注意:这里写了一个简单的触发事件,此时可以观察到,已经产生了一个新的类:NSKVONotifying_Book也可以观察到它的父类是Book

附加知识

有些时候程序逻辑的需要,一个类想要实现手动的change notification发送,则必须重写NSObject实现的automaticallyNotifiesObserversForKey:方法,并对需要实现手动发送的key返回NO,其余则调用super。

对price属性关闭自动发送

+ (BOOL) automaticallyNotifiesObserversForKey:(NSString *)key {
    if ([key isEqualToString:@"price"]) {
        return NO;
    }
    return [super automaticallyNotifiesObserversForKey:key];
}

对price属性实现手动的change notification发送

- (void)setPrice:(NSString *)price
{
    [self willChangeValueForKey:@"price"];
    _price = price;
    [self didChangeValueForKey:@"price"];
}

本文部分内容转载自:https://www.jianshu.com/p/829864680648

上一篇下一篇

猜你喜欢

热点阅读