快速枚举与enumerateObjectsUsingBlock

时间:2013-08-04 23:46:07

标签: objective-c objective-c-blocks fast-enumeration

考虑:

- (void) testing {
    NSMutableArray * numbers = [NSMutableArray arrayWithCapacity:10000000] ;
    for (int i = 0 ; i < 10000000 ; ++i) {
        [numbers addObject:@(i)] ;
    }

    NSInteger (^sum)(NSInteger, NSInteger) = ^(NSInteger running, NSInteger n) {
        return running + n ;
    } ;

    double start = ::CACurrentMediaTime() ;
    __block NSInteger running = 0 ;
    for (NSNumber * n in numbers) {
        running = sum(running, [n integerValue]) ;
    }
    running = 0 ;
    double end1 = ::CACurrentMediaTime() ;
    [numbers enumerateObjectsUsingBlock:^(NSNumber * n, NSUInteger idx, BOOL *stop) {
        running = sum(running, [n integerValue]) ;
    }] ;
    double end2 = ::CACurrentMediaTime() ;

    ::NSLog(@"fastEnum: %0.3f, enumUsingBlock: %0.3f", end1-start, end2-end1) ;
}

输出:

2013-08-05 00:38:34.852 WC[48299:a0b] fastEnum: 0.341, enumUsingBlock: 1.358

这表示enumerateObjectsUsingBlock比常规迭代慢4倍。

什么时候使用其中一个? enumerateObjectsUsingBlock提供的“增值”是什么证明其成本合理?

1 个答案:

答案 0 :(得分:4)

Mattt Thompson写了一篇关于使用Objective-C迭代的许多方法的great post on NSHipster

enumerateObjectsUsingBlock提供的附加值是给出对象的索引和NSEnumerationOptions

enum {
   NSEnumerationConcurrent = (1UL << 0),
   NSEnumerationReverse = (1UL << 1),
};
typedef NSUInteger NSEnumerationOptions;

引用马特:

  

除非你在迭代时确实需要数字索引,否则使用for / in NSFastEnumeration循环几乎总是更快。

     

(...)

     

同样,快速枚举几乎肯定比块枚举快得多,但是如果您已经使用了块,这些选项可能会很有用。