美文网首页程序员
十:KVO底层原理探究

十:KVO底层原理探究

作者: Mr姜饼 | 来源:发表于2021-01-08 13:41 被阅读0次

KVO介绍:

KVO,全称为Key-Value observing,中文名为键值观察,KVO是一种机制,它允许将其他对象的指定属性的更改通知给对象。

KVO的使用1(KeyPath):

1.添加观察者

[self.dog addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew context:NULL];

2.监听观察者

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
    if ([keyPath isEqualToString:@"name"]) {
        NSLog(@"%@",change);
    }
}

3.移除观察者:(必须一一对应,添加了,再释放的时候就需要移除)

[self.dog removeObserver:self forKeyPath:@"name" context:NULL];

KVO的使用2(context):

//定义context
static void *PersonNickContext = &PersonNickContext;
static void *PersonNameContext = &PersonNameContext;

//注册观察者
[self.person addObserver:self forKeyPath:@"nick" options:NSKeyValueObservingOptionNew context:PersonNickContext];
[self.person addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew context:PersonNameContext];
    
    
//KVO回调
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
    if (context == PersonNickContext) {
        NSLog(@"%@",change);
    }else if (context == PersonNameContext){
        NSLog(@"%@",change);
    }
}

KVO的自动触发和手动触发:

// 自动触发
+ (BOOL) automaticallyNotifiesObserversForKey:(NSString *)key{
    return YES;
}
//手动触发
+ (BOOL) automaticallyNotifiesObserversForKey:(NSString *)key{
    return NO;
}
- (void)setName:(NSString *)name{
    //手动开关
    [self willChangeValueForKey:@"name"];
    _name = name;
    [self didChangeValueForKey:@"name"];
}

KVO观察多个属性:

//1、合二为一的观察方法
+ (NSSet<NSString *> *)keyPathsForValuesAffectingValueForKey:(NSString *)key{
    
    NSSet *keyPaths = [super keyPathsForValuesAffectingValueForKey:key];
    if ([key isEqualToString:@"wallet"]) {
        NSArray *affectingKeys = @[@"rmb", @"dollars"];
        keyPaths = [keyPaths setByAddingObjectsFromArray:affectingKeys];
    }
    return keyPaths;
}

//2、注册KVO观察
[self.person addObserver:self forKeyPath:@"wallet" options:(NSKeyValueObservingOptionNew) context:NULL];

//3、触发属性值变化
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    self.person.dollars += 1;
    self.person.rmb  += 1;
}

//4、移除观察者
- (void)dealloc{
    [self.person removeObserver:self forKeyPath:@"wallet"];
}

KVO观察可变数组:

kvo观察机制是基于 setValue 之上的,而可变数组在进行 addObject、removeObject等操作的时候,并不会触发 setValue 的方法,故此kvo会失效,这时候我们需要改进,在取我们的数组的时候要进行另一种方法去取

[[self mutableArrayValueForKey:@"dataSource"] addObject:@"ss"];

**KVO观察属性,但不会观察成员变量

属性比成员变量多一个set 和 get 方法,所以在改变其值的时候会触发kvo,但是成员变量并不会触发kvo


KCO底层实现原理探究:

1.注册KVO观察者后,观察对象的isa指针指向会发生改变
2.派生出来的类会重写原有类的set方法
3.当set方法监听到新值的变化,则回调监听,将监听结果告知观察者
4.移除观察者时,isa指针会重新指向原有类
5.派生类并不会随着移除操作而销毁,会一直存在于内存中

代码探究原理

  • 注册观察者之前:实例对象person的isa指针指向LGPerson
image.png
  • 注册观察者之后:实例对象person的isa指针指向NSKVONotifying_LGPerson


    image.png
  • 移除观察者之后:实例对象的isa指向更改为LGPerson类


    image.png

相关文章

  • 十:KVO底层原理探究

    KVO介绍: KVO,全称为Key-Value observing,中文名为键值观察,KVO是一种机制,它允许将其...

  • 2018-02-14

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

  • 探究KVC的底层实现原理

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

  • 自定义KVO

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

  • 探究KVO底层原理

     本文将会分成三部分,一是简述KVO的底层原理,二是详解系统的KVO,三是自己手动实现KVO,我们通过断点调试、N...

  • iOS面试题整理

    1.探究KVO的底层实现原理 https://www.jianshu.com/p/829864680648 ·KV...

  • 底层原理探究(一)KVO

    问题:1、KVO的使用?实现原理?(为什么要创建子类来实现)2、KVC的使用?实现原理?(KVC拿到key以后,是...

  • Today面试

    Runloop 底层原理Kvo 底层原理ARC 底层原理 如何实现GCD 底层原理Block 底层原理Aut...

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

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

  • 探究KVO的底层实现原理

    KVO基本原理:1.KVO是基于runtime机制实现的 2.当某个类的属性对象第一次被观察时,系统就会在运行期动...

网友评论

    本文标题:十:KVO底层原理探究

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