从NSMutableArray中移除对象

16

我在设置for循环时偶然发现了以下快捷方式(相对于我一直在使用的教科书示例而言):

for (Item *i in items){ ... }

相对于更长的格式:

for (NSInteger i = 0; i < [items count]; i++){ ... } //think that's right
如果我使用更短的版本,是否有一种方法可以删除当前正在迭代的项(即“i”)?还是我需要使用较长的格式?

第一个for循环被称为增强型FOR循环,而第二个则是传统的标准FOR循环。在我学习Java认证时,我了解了这一点。 - Popeye
如果你真的需要在迭代数组时删除其中的元素,而且你不能像@Vladimir建议的那样之后再使用removeObjectsInArray:removeObjectsAtIndexes:来删除它们,那么你总是可以遍历原始数组的副本。 - Tiago
5个回答

32

快速枚举数组时不能删除其中的对象:

枚举是“安全”的—枚举器有一个突变保护,以便在枚举期间尝试修改集合时会引发异常。

无论如何,在枚举容器时为什么要改变它呢?考虑存储需要删除的元素,并使用removeObjectsInArray:removeObjectsAtIndexes:方法从容器中删除它们。


谢谢。我正在枚举时更改它,因为它是一个临时队列。我将所有项目移动到另一个数组中。 - Ben Packard
1
如果你想把所有的对象移动到另一个数组中,请尝试以下方法:[destinationArray addObjectsFromArray: sourceArray]; [sourceArray removeAllObjects]; - JeremyP

9

在删除项目后,只需添加关键字break;即可...

for(id item in items) {
    if([item isEqual:itemToDelete]) {
        [items removeObject:item];
        break; // A very important line 
    }
}

4
@Abdullah71的id永远不使用*。 - rptwsthi
1
这将删除一个对象并停止迭代,因此可能会错过应该被删除的其他对象。因此,仅在每次迭代需要删除零到一个对象时才使用它。 - marsbear

7

在枚举期间,Objective-C集合不得被修改。

您可以使用以下变体从集合中删除对象:

for (NSInteger i = items.count - 1; i >= 0 ; i--) {
   [items removeObjectAtIndex:i];
}

1
在我看来,如果你的业务逻辑允许从后往前遍历数组,那么最简单的正确方法就是这样做。 - marsbear

1

前面的循环是Objective C中的“for-each”循环。

*i是指向items-Array中直接项的指针(大多数情况下这将是NSMutableArray)。

这样你就可以直接操作该项:

[items removeObject: i];

这个(应该)可以工作 - 我目前没有在我的 Mac 上工作,无法检查它。 然而,可能是 Objective-C 防止在迭代集合时删除对象(这在大多数语言中都很常见)。


确实如此,当您枚举 NSMutableArray 时无法删除(或突变)它,因此 removeObject: 调用会引发异常。(正如弗拉基米尔在他的答案中所解释的那样) - Nick Forge

0

我使用这段代码来实现这个功能:

for (NSUInteger i = [items count] - 1; ; i--) {
     [items removeObjectAtIndex:i];
}

只有当i等于-1时才会崩溃 :) - marsbear

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接