Objective C中两种迭代方式的区别?

时间:2012-02-27 10:22:08

标签: iphone ios ios5 xcode4.2

我有两种迭代方式的问题。

NSArray *array=[[NSArray alloc] initWithObjects:@"A",@"B",@"C",@"D",nil];

NSMutableArray *mutArray=[[NSMutableArray alloc] initWithArray:array];

当我这样做时,它的工作正确

for (int i=0;[mutArray count]!=0;) {
    [mutArray removeObjectAtIndex:i];
}
NSLog(@"%d,",[mutArray count]);

但是,当我这样做时,它正在崩溃......为什么?

for(id obj in mutArray)
{
    [mutArray removeObject:obj]
}
NSLog(@"%d,",[mutArray count]);

请给我第二种情况的解决方案。

4 个答案:

答案 0 :(得分:2)

在快速枚举集合时,不得改变集合。

快速枚举通过从集合中请求一组元素来工作。它是为了性能和正确性。由于您在一片元素上进行枚举,因此程序不需要一直往返于容器。但是如果你改变枚举器后面的集合,那么所有对正确性和对象生存期的保证都会丢失。

在这种情况下,您会在控制台中看到错误。

另请参阅:-removeAllObjects

答案 1 :(得分:2)

第二种情况称为快速枚举。由于快速枚举的实现细节,您无法在快速枚举数组时对其进行编辑。

我经常通过以下方式解决这个问题:

for(id obj in [[mutArray copy] autorelease])
{
    [mutArray removeObject:obj]
}
NSLog(@"%d,",[mutArray count]);

这样你就可以对数组的临时副本进行迭代,但是你可以在经历时修改原文。

P.S。您无法在快速枚举期间进行编辑,因为快速枚举的工作原理是在枚举开始时向对象询问内容的C数组。一旦获得,迭代很快,因为枚举之间没有Objective-C消息调用。但是,如果修改数组,则C数组将不再是内容的有效表示,因此会引发异常。

答案 2 :(得分:0)

我的建议:

NSMutableArray *temps = [NSMutableArray array];
for(id obj in mutArray)
{
    // checking condition here
    [temps addObject:obj];
}
[mutArray removeObjectsInArray:temps];

答案 3 :(得分:0)

对集合进行变异会使枚举器无效。枚举器“检测”更改并触发错误。在快速枚举中,您可以标记需要删除的内容或在第一位使用索引。