例如:
NSMutableArray *array = [NSMutableArray arrayWithObjects:@"A", @"B", @"C", nil];
[array enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
if ([obj isEqualToString:@"A"]) {
[array removeObject:obj];
}
}];
NSLog(@"%@", array);
控制台打印B,C
。
但是:
NSMutableArray *array = [NSMutableArray arrayWithObjects:@"A", @"B", @"C", nil];
[array enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
if ([obj isEqualToString:@"A"]) {
[array removeObject:obj];
} else if ([obj isEqualToString:@"B"]) {
[array removeObject:obj];
}
}];
NSLog(@"%@", array);
控制台打印B,C
。
为什么“ B,C”不是“ C”?
枚举时删除数组中的obj会发生什么?
答案 0 :(得分:1)
在第一次迭代中,您将获得索引零值'A'。如果条件满足。然后删除A。现在,第二次迭代索引为1。索引为1的对象是C。因为您删除了“ A”,所以B移至零索引。因此,在第二次迭代中,它检查C而不是B。这就是为什么不删除B的原因。
答案 1 :(得分:1)
枚举器按顺序在对象上运行。首次输入块obj = array[0]
表示obj = @"A"
。然后array[0]
被删除。下次输入块obj = array[1]
时,但array
现在是@[@"B", @"C"]
,所以obj = @"C"
。您永远不会在@"B"
上进行迭代,因此无法将其删除。
通常,交替数组在遍历它们时非常危险,因此不建议使用。还有其他方法可以从数组中删除对象。
答案 2 :(得分:1)
可能的方法是迭代数组并存储要删除的索引
答案 3 :(得分:1)
在其他答案中正确提到了代码不起作用的原因,索引被修改了。
如果要在枚举数组时删除对象,则必须枚举始终向后。
在删除索引1处的项目后,索引0保持不变。
NSMutableArray *array = [NSMutableArray arrayWithObjects:@"A", @"B", @"C", nil];
[array enumerateObjectsWithOptions: NSEnumerationReverse usingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
if ([obj isEqualToString:@"A"]) {
[array removeObject:obj];
} else if ([obj isEqualToString:@"B"]) {
[array removeObject:obj];
}
}];
NSLog(@"%@", array);
答案 4 :(得分:0)
更改您要迭代的集合有时很难理解。有充分的理由避免它,即使您的情况也很简单。 (但是,当您删除数组的其他元素时,这些解决方案会很快中断。)
有一些通用的解决方案:
A。遍历副本
NSMutableArray *array = [NSMutableArray arrayWithObjects:@"A", @"B", @"C", nil];
NSArray *iterationArray = [array copy];
[iterationArray enumerateObjectsWithOptions: NSEnumerationReverse usingBlock:
^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
if ([obj isEqualToString:@"A"]) {
[array removeObject:obj];
} else if ([obj isEqualToString:@"B"]) {
[array removeObject:obj];
}
}];
B。存储要删除的对象
NSMutableArray *array = [NSMutableArray arrayWithObjects:@"A", @"B", @"C", nil];
NSMutableArray *itemsToRemove = [NSMutableArray new];
[array enumerateObjectsWithOptions: NSEnumerationReverse usingBlock:
^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
if ([obj isEqualToString:@"A"]) {
[itemsToRemove addObject:obj];
} else if ([obj isEqualToString:@"B"]) {
[itemsToRemove addObject:obj];
}
}];
[array remveObjects:itemsToRemove];
所有这些方法包括您的方法可能会导致意外结果,因为-removeObject:
会删除对象在数组本身中出现的所有,这意味着删除所有与arg相等的对象,包括不相同的对象。
C。删除具有该索引的对象
如果您要使用索引进行迭代(或者可以轻松地建立索引),则存储索引然后再使用该索引删除将更加有效。这使您有机会在相等和相同的对象之间进行区分。就您而言
NSMutableArray *array = [NSMutableArray arrayWithObjects:@"A", @"B", @"C", nil];
NSMutableIndexSet *itemsToRemove = [NSMutableIndexSet new];
__block NSUInteger index=0;
[array enumerateObjectsWithOptions: NSEnumerationReverse usingBlock:
^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop)
{
if ([obj isEqualToString:@"A"])
{
[itemsToRemove addIndex:index];
} else if ([obj isEqualToString:@"B"]) {
[itemsToRemove addIndex:index];
}
index++;
}];
[array removeObjectsAtIndexes:itemsToRemove];
NSLog(@"%@", array);