遇到的问题
需求是我需要在一个数组cellModelArray中添加许多对象(这些对象都是自定义模型类的model),获取的数据源中可能包含N个相同的模型,现在往cellModelArray这个数组中添加对象之前要检验一下该数组中是否已经包含一个相同的对象,如果不存在,才添加。
分析
如果一个数组里面包含的对象都是诸如NSString,NSNumber这样的元素,直接用cocoa提供的API就能直接判断数组是否包含给定的元素,但是对于自己定义的数据模型,就不是俺么简单了。我的解决办法是遍历原数组,根据数据模型里能唯一标识该对象的某一个属性判断是否已存在相同的元素,需要声明一个BOOL值记录判断结果。
主要代码如下:
__block BOOL isExist = NO;
[self.cellModelArray enumerateObjectsUsingBlock:^(WorkerEvaluateModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
if ([obj.workerName isEqualToString:cellModel.workerName]) {//数组中已经存在该对象
*stop = YES;
isExist = YES;
}
}];
if (!isExist) {//如果不存在就添加进去
[self.cellModelArray addObject:cellModel];
}```
###引申
其实这里可以引出一个关于怎么判断相等的问题,深入研究起来还是挺复杂的,这里贴一篇干货文章:[Thompson的文章](http://nshipster.com/equality/)
总之,就是在比较两个对象是否相等或者是判断一个对象是否在一个collection里面的时候,就要特别注意:
>- 对于普通的NSObject比较用isEqual:方法比较hash,上面那个文章的Thompson大叔说比较的是内存地址(我觉得挺有道理的不然普通的两个对象还在哪里有可比性==)
>- 对于Foundation里面的NSObject的子类如NSString、NSData、NSDate等(详细地还是看文章哈,反正没有NSArray╮(╯▽╰)╭),有定义相应的判断方法,所以用的话尽量采用子类中的比较方法
>- 对于自己定义的类的话,如果要用到比较,就要重新实现isEqual:和hash方法,实现的方法还有栗子什么Thompson大叔也说了,嗯不然会很容易悲剧的╮(╯_╰)╭
######备注:使用快速枚举for-in或者enumerate枚举器对数组进行遍历时不能修改数组(包括增加,删除和给对象赋值等操作),如果执意如此,便会报错,抛异常如下:
*** Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection <__NSArrayM: 0x7c873ea0> was mutated while being enumerated.