for-in 方式在遍歷數(shù)據(jù)源開(kāi)始時(shí),數(shù)據(jù)源的個(gè)數(shù)就已經(jīng)確定,在遍歷時(shí)修改數(shù)據(jù)源并不會(huì)改變開(kāi)始時(shí)確定下來(lái)的數(shù)據(jù)源個(gè)數(shù).所以在for-in 循環(huán)內(nèi)刪除數(shù)據(jù)源數(shù)據(jù)經(jīng)常會(huì)造成程序 crash. 下面是總結(jié)的一些遍歷刪除數(shù)據(jù)源數(shù)據(jù)的幾種方式:
NSMutableArray *origArr = [NSMutableArray arrayWithObjects:@"1",@"5",@"6",
@"1",@"2",@"8",
@"1",@"5",@"7",
nil];
先來(lái)看一下錯(cuò)誤的方式:
報(bào)錯(cuò)原因:*** 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循環(huán)
for (int i = 0; i < origArr.count; i++) {
NSString *str = [origArr objectAtIndex:i];
if ([str isEqualToString:@"1"]) {
[origArr removeObject:str];
}
}
//方式二:采用 for-in, 添加 break 語(yǔ)句
for (NSString *str in origArr) {
if ([str isEqualToString:@"1"]) {
[origArr removeObject:str];
break;
}
}
//方式三:新建一個(gè)副本數(shù)據(jù)源,遍歷副本數(shù)據(jù)源,然后在原數(shù)據(jù)源內(nèi)刪除數(shù)據(jù)
NSMutableArray *copyArr = [NSMutableArray arrayWithArray:origArr];
for (NSString *str in copyArr) {
if ([str isEqualToString:@"1"]) {
//在原數(shù)據(jù)源內(nèi)刪除數(shù)據(jù)
[origArr removeObject:str];
}
}
//方式四:逆序遍歷,然后刪除數(shù)據(jù)
NSEnumerator *enumeretor = [origArr reverseObjectEnumerator];
for (NSString *str in enumeretor) {
if ([str isEqualToString:@"1"]) {
[origArr removeObject:str];
}
}
--- END ---