web-dev-qa-db-ja.com

enumerateObjectsUsingBlockのBOOL * stop引数とは何ですか?

私は最近、高速列挙のニーズのためにenumerateObjectsUsingBlock:を頻繁に使用してきましたが、列挙ブロックでのBOOL *stopの使用法を理解するのに苦労しています。

NSArrayクラス参照状態

stop:ブール値への参照。ブロックは、値をYESに設定して、配列のさらなる処理を停止できます。 stop引数は、出力専用の引数です。ブロック内でこのブール値をYESにのみ設定する必要があります。

そのため、もちろん次のブロックを追加して列挙を停止できます。

if (idx == [myArray indexOfObject:[myArray lastObject]]) {
    *stop = YES;
}

私が伝えたことから、*stopYESに明示的に設定しなくても、悪影響はありません。列挙は、配列の最後で自動的に停止するようです。ブロックで*stopの使用は本当に必要ですか?

85
Mick MacCallum

ブロックの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];
}

[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];
}];

これは、呼び出しスコープからの変数への参照であるため、出力パラメーターです。ブロック内に設定する必要がありますが、enumerateObjectsUsingBlock:NSErrorsがフレームワークの呼び出しからコードに一般に返されるのと同じ方法。

- (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;
        }
    }
}
155
Josh Caswell