我不熟悉的循环奇怪:“for(id * in *)”

时间:2013-05-23 22:45:39

标签: objective-c for-loop fast-enumeration

如果这个问题非常简单,我很抱歉,但我已经用Google搜索过疯狂,无法找到合适的解释。

for (id line in self.lines){
    [linesCopy addObject:[line copyWithZone:zone]];
}

我只是在学习Objective-C,这是我以前从未见过的for循环形式。我熟悉简单的

for (int x = 1, x < 10, x++)

for循环的样式。

4 个答案:

答案 0 :(得分:11)

来自Cocoa Core Competencies: Enumeration

  

快速枚举

     

几个Cocoa类(包括集合类)采用NSFastEnumeration协议。您可以使用它来使用类似于标准C for循环的语法来检索实例持有的元素,如以下示例所示:

NSArray *anArray = // get an array;
for (id element in anArray) {
    /* code that acts on the element */
}
     

顾名思义,快速枚举比其他形式的枚举更有效。

如果您不知道,id是Objective-C类型,基本上意味着“指向任何Objective-C对象的指针”。请注意,id的指针内置于其中;你经常想说id *

如果您希望anArray的元素属于特定类,例如MyObject,则可以使用它:

for (MyObject *element in anArray) {
    /* code that acts on the element */
}

但是,编译器和运行时都不会检查元素是否确实是MyObject的实例。如果anArray的元素不是 MyObject的实例,您可能最终会尝试向其发送一条它不理解的消息,并获得一个选择器 - 未被承认的例外。

答案 1 :(得分:1)

它被称为forin循环,也称为快速枚举。基本上,语法是:

for (SomeObjectIAmExpecting *localVariableName in anArrayOfObjects)
{
    if (![localVariableName isKindOfClass:[SomeObjectIAmExpecting class]]) continue; //To avoid errors.
     //do something to them
}

答案 2 :(得分:1)

这是这种常见形式的速记等同物:

for (int i = 0; i < [self.lines count]; i++) {
    id line = [self.lines objectAtIndex:i];
    // ...
}

这是一种常见的循环习语(一次遍历一些集合,数组,集合等项目),它已被转换为这样的速记形式,称为“快速枚举”。

事实上,在其内部实现中,它实际上比自己做得快一些,所以它更适合清晰度和性能。

答案 3 :(得分:1)

这是一个可以与符合NSFastEnumeration协议的类一起使用的语句。当您有这个时,Objective-C编程指南建议您使用它。看看here。这是一种在没有传统for (int i = 0; i < length; ++i)语法的情况下迭代集合的方法。

请注意,在通过这种方式迭代时,它通常不支持删除和插入元素(也可以使用普通的for循环,在任何情况下都应该注意索引)。

基本上所有标准集合都支持这种迭代方式。