Objective-C enumerateObjectsUsingBlock与快速枚举? [英] Objective-C enumerateObjectsUsingBlock vs fast enumeration?

查看:124
本文介绍了Objective-C enumerateObjectsUsingBlock与快速枚举?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下两种方法的优缺点是什么?

What are the advantages and disadvantages of the following two approaches:

使用块进行枚举

enumerate using block

NSArray *myArray = [NSArray new];
[myArray enumerateObjectsUsingBlock:^(id anObject, NSUInteger idx, BOOL *stop) {
    if (anObject == someOtherObject) {
        [anObject doSomething:idx];
        *stop = YES;
    }
}];

fast enumeration

NSArray *myArray = [NSArray new];
int idx = 0
for (id anObject in myArray) {
    if (anObject == someOtherObject) {
        [anObject doSomething:idx];
        break;
    }
    ++idx;
}

推荐答案

This blog post covers the major differences. In summary:

  • 快速枚举在OS X 10.5+上可用,块在10.6+上可用
  • 对于简单枚举,快速枚举比基于块的枚举要快
  • 使用基于块的枚举比使用快速枚举更容易(并且性能更高)
  • NSDictionary上进行枚举时,您可以使用基于块的枚举数次获得键和值,而在快速枚举中,必须使用键在单独的消息发送中检索值.
  • Fast enumeration is available on OS X 10.5+, blocks are available on 10.6+
  • For simple enumeration, fast enumeration is a bit faster than block-based enumeration
  • It's easier (and more performant) to do concurrent or reverse enumeration with block-based enumeration than with fast enumeration
  • When enumerating over an NSDictionary you can get key and value in one hit with a block-based enumerator, whereas with fast enumeration you have to use the key to retrieve the value in a separate message send.

关于最后一点(NSDictionary枚举),请进行以下比较:

Regarding the last point (NSDictionary enumeration), compare this:

for (id key in dictionary)
{
    id obj = [dictionary objectForKey: key];
    // do something with key and obj
}

对此:

[dictionary enumerateKeysAndObjectsUsingBlock: ^(id key, id obj, BOOL *stop) {
    // do something with key and obj
}];

此外,这两种方法都可以防止可变集合在枚举循环内发生突变.有趣的是,如果您尝试在基于块的枚举中对集合进行突变,则会得到CoreFoundation的__NSFastEnumerationMutationHandler引发的异常,这表明存在一些通用代码.

In addition, both methods protect mutable collections from mutation inside the enumeration loop. Interestingly, if you try to mutate the collection inside a block-based enumeration, you get an exception thrown by CoreFoundation's __NSFastEnumerationMutationHandler, suggesting that there's some common code under the hood.

 NSMutableArray *myArray = [NSMutableArray arrayWithObjects:@"a", @"b", nil];
 [myArray enumerateObjectsUsingBlock:^(id anObject, NSUInteger idx, BOOL *stop) {
     // Attempt to mutate the array during enumeration
     [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"

这篇关于Objective-C enumerateObjectsUsingBlock与快速枚举?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆