有时候我们会想监听一个可变数组的变化来执行一些操作
但是直接监听当前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"]) {
...
}
}