关于KVO底层,看它就够了(三:KVO观察数组)

2019-04-08  本文已影响0人  OXHO

关于容器类,应该这样监听:
方法一:新建一个容器,去替换(仅提供想法,因为很Low,不推荐使用)
方法二:通过KVO观察容器属性的变化,利用KVC方法!!

直接上代码:

#import "ViewController.h"
#import "Person.h"
#import "Cat.h"
#import "NSObject+HOKVO.h"
#import <objc/message.h>
@interface ViewController ()

@property (nonatomic,strong)Person *p;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    Person *p = [[Person alloc]init];
    p.arr = [NSMutableArray arrayWithObjects:@"Aa",@"Bb", nil];

    [p addObserver:self forKeyPath:@"arr" options:NSKeyValueObservingOptionNew context:NULL];
//    [p Ho_addObserver:self forKeyPath:@"ary" options:NSKeyValueObservingOptionNew context:NULL];
    _p = p;
}


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

//点击屏幕
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{

    //通过KVO观察容器属性的变化,利用KVC方法!!
//    [_p.arr addObject:@"Cc"];//这个方法监听不了,所以屏蔽
    NSMutableArray *tempArr = [_p mutableArrayValueForKey:@"arr"];//这就是把_p.arr和tempArr 利用kvc进行绑定!
    [tempArr addObject:@"Cc"];
//    NSLog(@"tempArr = %@",tempArr);
    
}
@end

重点就是点击屏幕以后的方法,试试看,是不是就能监听数组了。

有心的同学发现,打印输出的kind从1变成了2

以下是源码里面的枚举

typedef NS_ENUM(NSUInteger, NSKeyValueChange) {
    NSKeyValueChangeSetting = 1,
    NSKeyValueChangeInsertion = 2,
    NSKeyValueChangeRemoval = 3,
    NSKeyValueChangeReplacement = 4,
};

//kind类型:
//1 NSKeyValueChangeSetting 观察的是set方法,返回1
//2. NSKeyValueChangeInsertion 插入。返回2
//3. NSKeyValueChangeRemoval 删除。返回3
//4. NSKeyValueChangeReplacement 替换。返回4

网上有说法,KVO是基于KVC,其实,确切的说,KVC算是KVO的一个入口,因为本身,KVC内部就有很多触发KVO通知的方法,这句话什么意思呢,我给大伙儿验证以下:

先看图1,是什么类型


图1

单步走一下:


图2

看到了吗?
变成了NotifyingMutableArray。这是NSMutableArray的子类,内部就是重写了addObserver方法,多了手动通知的willchange 和 didchange.

关于数组,还有一个重点,就是观察array的count值
[p.arr addObserver:self forKeyPath:@"count" options:NSKeyValueObservingOptionNew context:NULL];

如果这样写,会得到什么结果?
报错!
提示没有发现“count”!

因为,数组对count进行了一些安全性的操作;

上一篇 下一篇

猜你喜欢

热点阅读