web-dev-qa-db-fra.com

À quoi sert l'argument d'arrêt BOOL * pour enumerateObjectsUsingBlock: utilisé?

J'utilise enumerateObjectsUsingBlock: beaucoup ces derniers temps pour mes besoins d'énumération rapide, et j'ai du mal à comprendre l'utilisation de BOOL *stop dans le bloc d'énumération.

États de référence de la classe NSArray

stop: Une référence à une valeur booléenne. Le bloc peut définir la valeur sur YES pour arrêter le traitement ultérieur du tableau. L'argument stop est un argument de sortie uniquement. Vous ne devez jamais définir ce booléen sur YES dans le bloc.

Alors bien sûr, je peux ajouter ce qui suit dans mon bloc pour arrêter l'énumération:

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

D'après ce que j'ai pu dire, ne pas définir explicitement *stop à YES n'a pas d'effets secondaires négatifs. L'énumération semble s'arrêter automatiquement à la fin du tableau. Tout comme *stop vraiment nécessaire dans un bloc?

85
Mick MacCallum

L'argument stop du bloc vous permet d'arrêter l'énumération prématurément. C'est l'équivalent de break d'une boucle normale for. Vous pouvez l'ignorer si vous souhaitez parcourir tous les objets du tableau.

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

Il s'agit d'un paramètre out car il s'agit d'une référence à une variable de la portée appelante. Il doit être défini à l'intérieur de votre bloc, mais lu à l'intérieur de enumerateObjectsUsingBlock:, de la même manière que NSErrors sont généralement renvoyés à votre code à partir d'appels de framework.

- (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