今天修改数组里面的无效值时,使用了 for in 循环, 没想到竟然crash了. 当时我就无措了.代码如下
for( customModel *model in M_array ){
if ([model.name isEqualToString:@"***"]){
[M_array removeObject:model];
}
}
crash 原因: <_NSArrayM : >was mutated while being enumerated
为什么会造成crash呢?
因为快速遍历的原理是根据 enumerator对象内部的计数器,调用nextObject方法来实现返回下一个数组元素的. 知道元素全部返回就会返回nil,这就代表着整个enumerator对象就遍历完成了
#需要注意的是以这种原理来遍历enumerator对象的话, 无论对这个对象做什么操作, 对象的计数器都不会被重置!
找到的解决方法有以下几种:
- 1使用for循环遍历
for (int i= 0; i < M_array.count;i++){
customModel *model = M_array[i];
if([model.name isEqualToString:@"***"])
{
[M_array removeObject:model];
}
}
- 2如果还想使用for-in 来遍历的话也是可以的.
NSMutableArray *M_arrayCopy = [M_array mutableCopy];
for( customModel *model in M_arrayCopy ){
if ([model.name isEqualToString:@"***"])
{
[M_array removeObject:model];
}
}
- 3 对数组逆序遍历,查找对应的元素删除
NSEnumerator *enumerator = [M_array reverseObjectEnumerator];
for( customModel *model in enumerator ){
if ([model.name isEqualToString:@"***"])
{
[M_array removeObject:model];
}
}
- 4 使用
- (void)enumerateObjectsUsingBlock:(void (^)(ObjectType obj, NSUInteger idx, BOOL *stop))block;
[M_array enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
customModel *model = M_array[idx];
if ([model.name isEqualToString:@"***"]) {
[M_array removeObject:model];
}
}];
如有该文章有什么问题请留言或者私信我.谢谢!
参考:
官方文档:
https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSEnumerator_Class/index.html
开发者博客:
http://www.jianshu.com/p/a634310774a9
http://blog.csdn.net/zhangzhan_zg/article/details/38453305