关于容器类,应该这样监听:
方法一:新建一个容器,去替换(仅提供想法,因为很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,是什么类型

单步走一下:

看到了吗?
变成了NotifyingMutableArray。这是NSMutableArray的子类,内部就是重写了addObserver方法,多了手动通知的willchange 和 didchange.
关于数组,还有一个重点,就是观察array的count值
[p.arr addObserver:self forKeyPath:@"count" options:NSKeyValueObservingOptionNew context:NULL];
如果这样写,会得到什么结果?
报错!
提示没有发现“count”!
因为,数组对count进行了一些安全性的操作;
网友评论