iOS KVO监听可变数组变化

有时候我们会想监听一个可变数组的变化来执行一些操作
但是直接监听当前ViewController中的数组不管是count还是lastObject等都会导致崩溃 所以需要一些其他操作来达到目的

第一步

我们需要把数组包装一层 不需要另外单独写一个类 直接写在需要监听的ViewController中即可(可以写在ViewController的@interface之上 方便查看)

@interface ArrayModel : NSObject

@property (strong,nonatomic)NSMutableArray *dataArray;

@end

@implementation ArrayModel

-(NSMutableArray *)dataArray{
    if(!_dataArray){
        _dataArray = [NSMutableArray array];
    }
    return _dataArray;
}
@end

@interface ViewController ()
@end

@implementation ViewController
@end

第二步

在ViewController中声明包装数组的model并生成对象注册监听以及在dealloc中移除监听

@interface ViewController ()

@property (nonatomic, strong)ArrayModel *arrayModel;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    _arrayModel = [ArrayModel new];

    [_arrayModel addObserver:self forKeyPath:@"dataArray" options:NSKeyValueObservingOptionNew context:nil];
}

-(void)dealloc{
    [_arrayModel removeObserver:self forKeyPath:@"dataArray"];
}


@end

第三步

实现监听到数组改变后需要执行的代码

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context{
    
    if ([keyPath isEqualToString:@"dataArray"]) {
        
        ...
        
    }
}

第四步

在需要的地方对数组进行增删改
特别注意这里 千万不要用[array addObject:]这种方法要用下面的方法

[[_arrayModel mutableArrayValueForKeyPath:@"dataArray"] addObject:XXX];
[[_arrayModel mutableArrayValueForKeyPath:@"dataArray"] removeObject:XXX];
等等

这样就可以实现对数组的变化进行监听达到某些目的而不崩溃的效果

最终代码大概如下

@interface ArrayModel : NSObject

@property (strong,nonatomic)NSMutableArray *dataArray;

@end

@implementation ArrayModel

-(NSMutableArray *)dataArray{
    if(!_dataArray){
        _dataArray = [NSMutableArray array];
    }
    return _dataArray;
}
@end

@interface ViewController ()

@property (nonatomic, strong)ArrayModel *arrayModel;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    _arrayModel = [ArrayModel new];

    [_arrayModel addObserver:self forKeyPath:@"dataArray" options:NSKeyValueObservingOptionNew context:nil];
}

-(void)dealloc{
    [_arrayModel removeObserver:self forKeyPath:@"dataArray"];
}
@end

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context{
    
    if ([keyPath isEqualToString:@"dataArray"]) {
        
        ...
        
    }
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • *面试心声:其实这些题本人都没怎么背,但是在上海 两周半 面了大约10家 收到差不多3个offer,总结起来就是把...
    Dove_iOS阅读 27,276评论 30 472
  • iOS网络架构讨论梳理整理中。。。 其实如果没有APIManager这一层是没法使用delegate的,毕竟多个单...
    yhtang阅读 5,333评论 1 23
  • 转至元数据结尾创建: 董潇伟,最新修改于: 十二月 23, 2016 转至元数据起始第一章:isa和Class一....
    40c0490e5268阅读 1,857评论 0 9
  • 最近项目中处理kvo 的时候,遇到一个问题:当我操作的时候,会发现kvo 释放的时候,会崩溃, 崩溃日志如下: /...
    那是一阵清风_徐来阅读 5,518评论 0 11
  • 文/叶抒 月寒霜落惊飞鹊,鹊飞惊落霜寒月。 蝉秋居高阁,阁高居秋蝉。 睡后方知醉,醉知方后睡。 ...
    叶抒阅读 306评论 2 4