这篇博客文章涵盖了主要区别。总结如下:
- 快速枚举在OS X 10.5+上可用,块在10.6+上可用
- 对于简单的枚举,快速枚举比基于块的枚举略快一点
- 使用基于块的枚举比使用快速枚举更容易(及性能更好)进行并发或反向枚举
- 当枚举
NSDictionary
时,使用基于块的枚举器可以一次获取键和值,而使用快速枚举需要使用键来单独检索值。
关于最后一点(NSDictionary枚举),请参考以下内容:
for (id key in dictionary)
{
id obj = [dictionary objectForKey: key];
}
变成这样:
[dictionary enumerateKeysAndObjectsUsingBlock: ^(id key, id obj, BOOL *stop) {
// do something with key and obj
}];
此外,这两种方法都可以保护可变集合免于在枚举循环内部发生突变。有趣的是,如果您试图在基于块的枚举中改变集合,您将会被 CoreFoundation 的 __NSFastEnumerationMutationHandler
抛出异常,这表明底层存在一些公共代码。
NSMutableArray *myArray = [NSMutableArray arrayWithObjects:@"a", @"b", nil];
[myArray enumerateObjectsUsingBlock:^(id anObject, NSUInteger idx, BOOL *stop) {
[myArray addObject:@"c"];
}];
输出:
2011-12-14 22:37:53.716 Untitled[5809:707] *** Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection <__NSArrayM: 0x109614190> was mutated while being enumerated.'
*** First throw call stack:
(
0 CoreFoundation 0x00007fff8cca7286 __exceptionPreprocess + 198
1 libobjc.A.dylib 0x00007fff8319ad5e objc_exception_throw + 43
2 CoreFoundation 0x00007fff8cd311dc __NSFastEnumerationMutationHandler + 172
3 CoreFoundation 0x00007fff8cc9efb4 __NSArrayEnumerate + 612
4 Untitled 0x00000001094efcea main + 250
5 Untitled 0x00000001094efbe4 start + 52
6 ??? 0x0000000000000001 0x0 + 1
)
terminate called throwing an exceptionRun Command: line 1: 5809 Abort trap: 6 ./"$2"