NSMutableArray *array = [[NSMutableArray alloc] initWithArray:@[@"1", @“2", @“3", @“4", @“5"]];
for (NSString *str in array) {
if ([str isEqualToString:@“3"]) {
[array removeObject:str];
}
}
NSLog(@“数组:%@“,array);
崩溃错误:<__NSArrayM: 0xb550c30> was mutated while being enumerated.’
当程序出现这个提示的时候,是因为用快速遍历forin遍历数组,又同时增或删这个数组里面的内容,导致数组count发生变化,猜测在forin快速遍历的内部有个内置的不会动态改变个数的计数器, 当你的数组做出增删后, 计数器并没有相应的增减, 这样就会导致继续通过计数器获取数组, 造成数组越界。
The enumerator raises an exception if you modify the collection while enumerating
//这句话说明苹果是不建议使用NSFastEnumeration(forin)的时候, 一边遍历一边修改集合
ou send "nextObject" repeatedly to a newly created NSEnumerator object to
have it return the next object in the original collection. When the collection
is exhausted, nil is returned. You cannot “reset” an enumerator after it has
exhausted its collection. To enumerate a collection again, you need a new enumerator.
//这句话要注意, nextObject是一个对象方法, 他的作用是取出集合中的一个元素后, 通过这个方法取出并返回"原始集合"中的下一个元素, 当集合遍历结束后, 返回nil. 并且你在遍历的过程中, 不能重新设置遍历器, 直到这个集合遍历结束
It is not safe to modify a mutable collection while enumerating through it.
Some enumerators may currently allow enumeration of a collection that is modified,
but this behavior is not guaranteed to be supported in the future.
//从上述看出来, 当使用快速遍历器的时候, 修改一个可变的集合, 是相当不安全的操作, 可能造成一些不可预知的问题
解决方案:
1.使用for循环 (array.count动态获取了array的个数,故不会崩溃)
for (int i = 0; i < array.count; i++) {
if (...) {
// do sth ;
}
}
2.使用临时变量(缺点:数据量大的时候,开辟新的内存,导致内存增加,用完最好手动释放)
NSArray *tempArray = [NSArray arrayWithArray:array];
for (id obj in tempArray) {
if ([obj iskindOfClass:[Object class]]) {
// do sth ;
}
}
tempArray = nil;
3.enumerateObjectsUsingBlock(苹果推荐)
[array enumerateObjectsUsingBlock:^(NSMutableDictionary *obj, NSUInteger idx, BOOL *stop) {
if (...) {
// do sth
*stop = YES;
}
}];
本文探讨了遍历NSMutableArray时删除元素导致的崩溃问题,并提供了三种安全的解决方案:使用for循环、临时变量及enumerateObjectsUsingBlock方法。
3891

被折叠的 条评论
为什么被折叠?



