Objective-C中的快速枚举(循环)是如何工作的?(例如:for (NSString *aString in aDictionary)...)

6
我正在实现一个针对相当复杂的表格的自定义搜索栏,并且又遇到了这个代码模式。以下是《Beginning iPhone Development》一书中的示例代码:
- (void)handleSearchForTerm:(NSString *)searchTerm
 {
NSMutableArray *sectionsToRemove = [[NSMutableArray alloc] init];
[self resetSearch];

for (NSString *key in self.keys)
  {
    NSMutableArray *array = [self.names valueForKey:key];
    NSMutableArray *toRemove = [[NSMutableArray alloc] init];
    for (NSString *name in array)
    {
        if ([name rangeOfString:searchTerm
                      options:NSCaseInsensitiveSearch].location == NSNotFound)
            [toRemove addObject:name];
    }

    if ([array count] == [toRemove count])
        [sectionsToRemove addObject:key];
    [array removeObjectsInArray:toRemove];
    [toRemove release];
  }
[self.keys removeObjectsInArray:sectionsToRemove];
[sectionsToRemove release];
[table reloadData];
}

我感兴趣的部分是“for (NSString *name in array)”这一段。这段代码实际上是在数组中遍历每个元素并创建一个字符串。对于字典类型,也可以使用类似的语法来遍历键值对。希望能帮到你!

谢谢大家的快速回复!我编辑了标题,加入了“快速枚举”。 - Jonah
3个回答

15

这种结构是一种不同类型的 for 循环,它遍历 Objective-C 集合中的项,而不是 C 数组。第一部分定义一个对象,该对象在每次循环中被设置为集合中的一个元素,而第二部分是要枚举的集合。例如,下面的代码:

NSArray *array = [NSArray arrayWithObjects:@"foo", @"bar", nil];
for(NSString *string in array) {
    NSLog(string);
}

将会打印:

foo
bar

这段代码定义了一个 NSString *string,在每次循环中,该变量被设置为 NSArray *array 中的下一个对象。

同样地,你也可以使用枚举来遍历 NSSet 的实例(其中对象的顺序未定义),以及 NSDictionary(它将枚举存储在字典中的键 - 你可以通过枚举键,然后调用 valueForKey: 并使用该键在字典中获取值)。

它非常类似于 C 中的结构:

int array[2] = { 0, 1 };
for(int i = 0; i < 2; i++) {
    printf("%d\n", array[i]);
}

它只是一种语法上更易读,并隐藏了在NSArray、NSSet或NSDictionary中列举对象所需的某些高级枚举的方法。更多细节请参阅《The Objective-C 2.0 Programming Language》文档中快速枚举部分。

输出结果为:
0
1

3
这被称为“快速枚举”。它遍历数组,将key设置为每个项。从功能上讲,它与执行以下操作相同:
NSString *key;
for ( NSInteger i = 0; i < [[ self keys ] count ]; i++ ) {
    key = [[ self keys ] objectAtIndex:i ];

    NSMutableArray *array = [self.names valueForKey:key];
    NSMutableArray *toRemove = [[NSMutableArray alloc] init];
    for (NSString *name in array)
    {
            if ([name rangeOfString:searchTerm
                  options:NSCaseInsensitiveSearch].location == NSNotFound)
                    [toRemove addObject:name];
    }

    if ([array count] == [toRemove count])
            [sectionsToRemove addObject:key];
    [array removeObjectsInArray:toRemove];
    [toRemove release];
}

2

这是一个循环,对于字典中的每个键执行一次迭代。

for..in结构称为快速枚举。您可以在Objective-C 2.0编程指南中了解更多信息。

它如何与对象配合工作取决于其实现NSFastEnumeration协议的方式。 NSDictionary类参考文档描述了它如何与字典一起使用:

在Mac OS X v10.5及更高版本中,NSDictionary支持NSFastEnumeration协议。您可以使用for…in结构枚举字典的键,如下面的示例所示。


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