1. ホーム
  2. objective-c

[解決済み] enumerateObjectsUsingBlock: の BOOL *stop 引数は何に使うのですか?

2023-04-04 23:28:05

質問

私はこれまで enumerateObjectsUsingBlock: をよく使うのですが、その使い方を理解するのに苦労しています。 BOOL *stop の使い方を理解するのに苦労しています。

NSArray クラスのリファレンスでは

stop : ブール値への参照。ブロックはこの値を YES に設定する。 に設定すると、配列のさらなる処理を停止します。このとき stop 引数はout-onlyです。 引数です。このブール値を YES に設定するだけです。 ブロック内で

そうすると、もちろんブロック内に以下を追加して、列挙を停止させることができます。

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

私が調べたところでは、明示的に *stopYES は、特に悪い副作用はありません。列挙は配列の終わりで自動的に停止するようです。ですから *stop を使うことは本当に必要なのでしょうか?

どのように解決するのですか?

この 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];
}];

これは呼び出し側のスコープから変数への参照であるため、outパラメータとなります。ブロックの内部で設定する必要がありますが、読み込みは 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;
        }
    }
}