Recorre la matriz para eliminar varios elementos de la matriz

Cuando recorremos la matriz de variables, es mejor no eliminar elementos de la matriz.
Debido a que la operación de eliminación puede causar el cambio de la capacidad de la matriz, resultando en problemas como la matriz fuera de límites.
Anteriormente encontré este problema al usar for loop traversal.
En ese momento, la práctica era usar enumerateObjectsUsingBlock :, pero cuando encontré este problema nuevamente esta vez, probé, por cierto, en enumerateObjectsUsingBlock: por cierto.
Los resultados experimentales son los siguientes:

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)

El resultado es normal.

Utilizar para en:

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

El resultado es un bloqueo, la información es la siguiente:

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

Usar para:

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)

El resultado es normal. Puede ser que Apple haya hecho correcciones en el procesamiento interno del bucle for ordinario. En el pasado, escribir de esta manera provocaba un error.

De hecho, la solución más correcta y segura es recorrer la matriz en orden inverso y luego eliminar los elementos.

Por ejemplo, recorrido inverso de for en:

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)

utilizar

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)

En el orden inverso de para

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)

Supongo que te gusta

Origin blog.csdn.net/woruosuifenglang/article/details/78466557
Recomendado
Clasificación