当用for in循环是会产生以下的错误:
Terminating app due to uncaught exception'NSGenericException',Collection was mutated while being enumerated.
究其原因是因为在遍历数组的同时,对当前数组进行了增删操作,造成的异常。
For in实际上是简单的快速枚举,不具有实时监测数组容器变化的功能。所以对于可变数组进行枚举操作时,不能通过添加或删除对象等这类操作来改变数组容器,否则就会报错.但是Objective C 提供一个Block的枚举器遍历方法可以觉察这一点:
(void)enumerateObjectsUsingBlock:(void (^)(ObjectType obj, NSUInteger idx, BOOL *stop))block;
官方文档的说明
Parameters
block
The block to execute for each object in the array.
The block takes three arguments:
obj
The object.
idx
The index of the object in the array.
stop
A reference to a Boolean value. Setting the value to YES within the block stops further enumeration of the array. If a block stops further enumeration, that block continues to run until it’s finished.
实例:
[tempArray enumerateObjectsUsingBlock:^(id obj, NSUInteger
idx, BOOL stop) {
if ([obj isEqualToString:@"red"]) {
*stop = YES;
if (stop == YES) {
[tempArray replaceObjectAtIndex:idx withObject:@"yellow"];
}
}
}];
当然除了这个方法外也有其他很实用的技巧,比如网友推荐的逆序遍历数组进行操作就可以避免该问题:
具体情况是这样的,当我们正序遍历时,如果删除了一个,那么没有遍历到的元素位置都会往前移动一位,这样系统就无法确定接下来遍历是从删除位置开始呢,还是从删除位置下一位开始呢?这样就造成程序crash了.对于逆序遍历就不会,因为我们逆序遍历时,遇到匹配的元素删除后,位置改变的是遍历过得元素,而没有遍历到的元素位置却没有改变,所以遍历能够正常进行
网友评论