for-in 方式在遍历数据源开始时,数据源的个数就已经确定,在遍历时修改数据源并不会改变开始时确定下来的数据源个数.所以在for-in 循环内删除数据源数据经常会造成程序 crash. 下面是总结的一些遍历删除数据源数据的几种方式:
NSMutableArray *origArr = [NSMutableArray arrayWithObjects:@"1",@"5",@"6",
@"1",@"2",@"8",
@"1",@"5",@"7",
nil];
先来看一下错误的方式:
报错原因:*** Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection <__NSArrayM: 0x100400e10> was mutated while being enumerated.'
for (NSString *str in origArr) {
if ([str isEqualToString:@"1"]) {
[origArr removeObject:str];
}
}
下面是几种可行方案:
//方式一:采用 for循环
for (int i = 0; i < origArr.count; i++) {
NSString *str = [origArr objectAtIndex:i];
if ([str isEqualToString:@"1"]) {
[origArr removeObject:str];
}
}
//方式二:采用 for-in, 添加 break 语句
for (NSString *str in origArr) {
if ([str isEqualToString:@"1"]) {
[origArr removeObject:str];
break;
}
}
//方式三:新建一个副本数据源,遍历副本数据源,然后在原数据源内删除数据
NSMutableArray *copyArr = [NSMutableArray arrayWithArray:origArr];
for (NSString *str in copyArr) {
if ([str isEqualToString:@"1"]) {
//在原数据源内删除数据
[origArr removeObject:str];
}
}
//方式四:逆序遍历,然后删除数据
NSEnumerator *enumeretor = [origArr reverseObjectEnumerator];
for (NSString *str in enumeretor) {
if ([str isEqualToString:@"1"]) {
[origArr removeObject:str];
}
}
--- END ---
网友评论