enumerateObjectsUsingBlock的BOOL*stop参数是什么:用于?

Mic*_*lum 85 cocoa-touch enumeration objective-c nsarray fast-enumeration

我最近一直在使用enumerateObjectsUsingBlock:很多我的快速枚举需求,而且我很难理解BOOL *stop枚举块中的用法.

NSArray类引用状态

stop:对布尔值的引用.该块可以将值设置YES为停止进一步处理数组.这个stop论点是一个唯一的论点.您应该只将此布尔值设置YES为块内.

那么当然我可以在我的块中添加以下内容来停止枚举:

if (idx == [myArray indexOfObject:[myArray lastObject]]) {
    *stop = YES;
}
Run Code Online (Sandbox Code Playgroud)

从我能够说的,没有明确设置*stopYES没有任何负面的副作用.枚举似乎在数组的末尾自动停止.那么*stop在一个区块中使用真的有必要吗?

Jos*_*ell 156

stop块的参数允许您过早地停止枚举.它等同break于正常for循环.如果要遍历数组中的每个对象,可以忽略它.

for( id obj in arr ){
    if( [obj isContagious] ){
        break;    // Stop enumerating
    }

    if( ![obj isKindOfClass:[Perefrigia class]] ){
        continue;    // Skip this object
    }

    [obj immanetizeTheEschaton];
}
Run Code Online (Sandbox Code Playgroud)
[arr enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
    if( [obj isContagious] ){
        *stop = YES;    // Stop enumerating
        return;
    }

    if( ![obj isKindOfClass:[Perefrigia class]] ){
        return;    // Skip this object
    }

    [obj immanentizeTheEschaton];
}];
Run Code Online (Sandbox Code Playgroud)

这是一个out参数,因为它是对调用范围的变量的引用.它需要在你的Block中设置,但是在内部读取enumerateObjectsUsingBlock:,就像NSError通常从框架调用传递回代码一样.

- (void)enumerateObjectsUsingBlock:(void (^)(id obj, NSUInteger idx, BOOL *stop))block {
    // N.B: This is probably not how this method is actually implemented!
    // It is just to demonstrate how the out parameter operates!

    NSUInteger idx = 0;
    for( id obj in self ){

        BOOL stop = NO;

        block(obj, idx++, &stop);

        if( stop ){
            break;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 请注意,`stop`标志是建议性的; 例如,枚举可以在并发情况下的某些未定义的迭代次数中继续.也就是说,你不应该在每次通过枚举时无条件地设置一个`__block`变量,并期望它在使用`stop`提前终止时是"最后"值.你应该总是将"不,使用这个对象"与设置`stop = YES;`结合起来. (21认同)
  • <rdar:// problem/15015199>现在要求澄清,因为文档没有说明任何方式,它应该. (4认同)