배열을 탐색하여 배열의 여러 요소를 삭제합니다.

변수 배열을 탐색 할 때 배열의 요소를 삭제하지 않는 것이 가장 좋습니다.
삭제 작업으로 인해 어레이 용량이 변경되어 어레이 범위를 벗어난 것과 같은 문제가 발생할 수 있기 때문입니다.
이전에는 for 루프 순회를 사용할 때이 문제가 발생했습니다.
그 당시에는 enumerateObjectsUsingBlock :을 사용하는 것이 관행 이었지만 이번에이 문제가 다시 발생했을 때 enumerateObjectsUsingBlock :을 테스트했습니다.
실험 결과는 다음과 같습니다.

NSMutableArray *array = [NSMutableArray arrayWithArray:@[@"1",@"2",@"3",@"4",@"5"]];
[array enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
    if ([obj isEqualToString:@"3"]) {
        [array removeObject:obj];
    }
}];
NSLog(@"%@",array);

// 输出结果:(1,2,4,5)

결과는 정상입니다.

사용 :

NSMutableArray *array = [NSMutableArray arrayWithArray:@[@"1",@"2",@"3",@"4",@"5"]];
for (NSString *obj in array) {
    if ([obj isEqualToString:@"3"]) {
        [array removeObject:obj];
    }
}
NSLog(@"%@",array);

결과는 충돌이며 정보는 다음과 같습니다.

2016-11-11 22:48:06.886 Solutions[15297:2231002] *** Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection <__NSArrayM: 0x1001060b0> was mutated while being enumerated.'
*** First throw call stack:
(
    0   CoreFoundation                      0x00007fff929c14f2 __exceptionPreprocess + 178
    1   libobjc.A.dylib                     0x00007fff8fcb2f7e objc_exception_throw + 48
    2   CoreFoundation                      0x00007fff92a2815c __NSFastEnumerationMutationHandler + 300
    3   Solutions                           0x0000000100000d1c main + 508
    4   libdyld.dylib                       0x00007fff90cd05ad start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException

사용:

NSMutableArray *array = [NSMutableArray arrayWithArray:@[@"1",@"2",@"3",@"4",@"5"]];
for (int i = 0; i < array.count; i++) {
    NSString *obj = array[i];
    if ([obj isEqualToString:@"3"]) {
        [array removeObject:obj];
    }
}
NSLog(@"%@",array);
// 输出结果是:(1,2,4,5)

결과는 정상이며, Apple이 일반 for 루프의 내부 처리를 수정 한 것일 수 있으며, 과거에는 이와 같이 작성하면 오류가 발생했습니다.

실제로 가장 정확하고 안전한 솔루션은 배열을 역순으로 탐색 한 다음 요소를 삭제하는 것입니다.

예를 들어 for in의 역방향 순회 :

NSMutableArray *array = [NSMutableArray arrayWithArray:@[@"1",@"2",@"3",@"4",@"5"]];
for (NSString *obj in array.reverseObjectEnumerator) {
    if ([obj isEqualToString:@"3"]) {
        [array removeObject:obj];
    }
}
NSLog(@"%@",array);
// 输出结果:(1,2,4,5)

사용하다

NSMutableArray *array = [NSMutableArray arrayWithArray:@[@"1",@"2",@"3",@"4",@"5"]];
[array enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            if ([obj isEqualToString:@"3"]) {
                [array removeObject:obj];
            }
        }];

NSLog(@"%@",array);
// 输出结果:(1,2,4,5)

for의 역순

NSMutableArray *array = [NSMutableArray arrayWithArray:@[@"1",@"2",@"3",@"4",@"5"]];
for (int i = array.count - 1; i >= 0; i--) {
    NSString *obj = array[i];
    if ([obj isEqualToString:@"3"]) {
        [array removeObject:obj];
    }
}
NSLog(@"%@",array);
// 输出结果:(1,2,4,5)

추천

출처blog.csdn.net/woruosuifenglang/article/details/78466557