美文网首页
iOS之KVO实现原理探究

iOS之KVO实现原理探究

作者: 内心戏十足的伪胖子 | 来源:发表于2018-09-07 11:03 被阅读53次

KVO,就是key-value-observing,键值观察者模式。开发中经常会使用到,并且面试大概率问到其底层实现原理。

用法

eg:

#import <Foundation/Foundation.h>
@interface Programmer : NSObject
@property (copy, nonatomic) NSString *name;
@end

#import "Programmer.h"
@implementation Programmer
- (void)setName:(NSString *)name {
    _name = name;
}
@end

#import "ViewController.h"
#import "Programmer.h"
#import <objc/runtime.h>

@interface ViewController ()

@property (strong, nonatomic) Programmer *programmer1;
@property (strong, nonatomic) Programmer *programmer2;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.programmer1 = [[Programmer alloc] init];
    self.programmer1.name = @"Bob";
    self.programmer2 = [[Programmer alloc] init];
    self.programmer2.name = @"Lili";
    
    NSLog(@"添加监听之前person1的isa指针指向%@",object_getClass(self.programmer1));//在调试模式下可以直接 po self.person1->isa
    NSLog(@"添加监听之前person类对象的isa指针指向%@",object_getClass(object_getClass(self.programmer1)));
    NSLog(@"添加监听之前person1的setName方法的地址%p",[self.programmer1 methodForSelector:@selector(setName:)]);//在调试模式下,通过 p (IMP)地址 打印出这个IMP地址对应的方法名称
    
    [self.programmer1 addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];
    
    NSLog(@"添加监听之后person1的isa指针指向%@",object_getClass(self.programmer1));
    NSLog(@"添加监听之后person类对象的isa指针指向%@",object_getClass(object_getClass(self.programmer1)));
    NSLog(@"添加监听之后person1的setName方法的地址%p",[self.programmer1 methodForSelector:@selector(setName:)]);
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    self.programmer1.name = @"Mark";
    self.programmer2.name = @"Jeny";
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
    NSLog(@"keyPath===%@",keyPath);
    NSLog(@"object===%@",object);
    NSLog(@"change===%@",change);
    NSLog(@"context===%@",context);
}
  1. 定义一个Programmer类,有一个name的property
  2. 然后在控制器中有一个@property (strong, nonatomic) Programmer *programmer1;
  3. 在ViewDidLoad中添加观察,[self.programmer1 addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];,NSKeyValueObservingOptionNew和NSKeyValueObservingOptionOld分别表示变化之前的值和改变之后的值
  4. 在监听的控制器中实现- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context这个方法,其中change为一个字典,里面包含新值和旧值

原理

上面的例子中:

  1. Programmer类的实例programmer1name属性被控制器监听了。这时,OC的runtime机制生成了一个KVONotifying_ Programmer的类
  2. programmer1实例的isa指针从指向Programmer的类对象,变成指向KVONotifying_ Programmer的类对象,而KVONotifying_ Programmer的isa指针指的是KVONotifying_ Programmer的meta-class元类对象,KVONotifying_ Programmer的superclass指针指的是Programmer的类对象
  3. 修改programmer1name属性的时候调用了Foundation框架下的一个_NSSetObjectValueAndNotify方法
  4. KVONotifying_ Programmer类重写了Programmer类属性name的setter方法加入了NSObject的两个方法:willChangeValueForKey:(值改变之前)和didChangevlueForKey:(值改变之后)。在一个被观察属性发生改变之前,willChangeValueForKey:一定会被调用,这就会记录旧的值。而当改变发生后,didChangeValueForKey:会被调用,继而observeValueForKey:ofObject:change:context:也会被调用。

探究

待续

如果有错误,感谢各位大佬指正。

相关文章

  • iOS之KVO实现原理探究

    KVO,就是key-value-observing,键值观察者模式。开发中经常会使用到,并且面试大概率问到其底层实...

  • iOS - KVO

    [toc] 参考 KVO KVC 【 iOS--KVO的实现原理与具体应用 】 【 IOS-详解KVO底层实现 】...

  • 自定义KVO

    导语: 如果对KVO原理不是很熟悉的,可以参考下简书另一篇文章《ios KVO原理探究》,主要是通过模拟KVO底层...

  • 2018-02-14

    探究KVO的底层实现原理 addObserver:forKeyPath:options:context:各个参数的...

  • iOS KVO原理的探究实现

    感觉很久都没有写新文章了,还是写一些小文章吧,记录一下也好!这一次和大家讲解的是KVO -- key value ...

  • 探究KVC的底层实现原理

    慕课网地址 以前写了关于的实现原理的文章,探究KVO的底层实现原理,现在我们也探究一下的底层实现 原理 的全称是K...

  • IOS底层(三) KVO底层实现原理

    @[TOC](IOS底层(三) KVO底层实现原理 ) 一,KVO简述 KVO的全称 Key-Value Obse...

  • iOS 自定义KVO

    自己实现kvo之前,需要知道iOS系统对kvo的实现。 系统实现kvo的原理 这依赖了OC强大的runtime特性...

  • iOS KVO原理探究

    通过指定类的属性名称,来达到类属性值的变化,分为手动和自动俩种模式,其中手动模式 需要在改变属性值的前后分别实现W...

  • iOS KVO原理探究

    导语: KVO全称Key Value Observing,直译为键值观察。KVO 作为 iOS 中一种强大并且有效...

网友评论

      本文标题:iOS之KVO实现原理探究

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