Y a-t-il un moyen de simuler une instruction code> code> dans un DISPATCH_APPLY () CODE>
bloc?
Par exemple, chaque API de cacao que j'ai vu traiter avec Les blocs énumérants ont un paramètre "Stop": p>
[array enumerateObjectsUsingBlock:^(id obj, NSUInteger i, BOOL *stop) { if ([obj isNotVeryNice]) { *stop = YES; // No more enumerating! } else { NSLog(@"%@ at %zu", obj, i); } }];
3 Réponses :
Je ne pense pas que Dispatch_apply soutient cela. La meilleure façon de penser à imiter qu'il serait de faire une variable booléenne __bloc, et de le vérifier au début du bloc. Si c'est ensemble, cautionnez-vous rapidement. Vous devrez toujours courir le bloc à travers le reste des itérations, mais ce serait plus rapide. P>
Vous ne pouvez pas dans La réponse @BJ est la réponse Le plus proche que vous puissiez faire, mais il y aura toujours un "déversement". P> break code> A
Dispatch_apply code> car il est illogique. p>
-EnumèrentObjecteBlock: code> Une pause est bien défini car les fonctions sont exécutées séquentiellement em>. Mais dans
Dispatch_apply code> Les fonctions sont exécutées en parallèle. Cela signifie à la
I = 3 code> RD Invocation du "bloc", le
i = 4 code> 00 appel aurait pu être démarré. Si vous
break code> au
i = 3 code>, si le
i = 4 code> appel est toujours exécuté? p>
Eh bien, ce n'est pas tout à fait vrai; Bien qu'il soit vrai que l'énumérantObjectBlock: est séquentielle, il y a aussi énumérableObjectSwithOptions: Utilisation de Block :. Ce paramètre "Options" peut être utilisé pour diriger que l'énumération devrait se produire simultanément. Je ne suis pas sûr de savoir comment ils le font en interne, mais je suppose que cela a été fait à l'aide d'un groupe Dispatch_Proupe qui permettrait un contrôle plus direct.
Mais le point est que énumérantObjectSwithOptions: UtilisationBlock: a toujours le * paramètre d'arrêt.
Il serait logique de soutenir l'arrêt de Dispatch_Apply (), mais il n'a pas eu de sens dans les objectifs de conception. Indiquant que le drapeau d'arrêt sur énumérerObjectBlock: code> existe à cause de l'exécution séquentielle implicite est fausse; Les deux sont complètement orthogonaux.
Par conception, Dispatch _ * () Code> Les API n'ont aucune notion d'annulation. La raison en est que c'est presque universellement vrai que votre code maintient le concept de quand arrêter ou non et, donc, également soutenir cela dans les API d'expédition _ * () serait redondant (et, avec une redondance vient des erreurs). Ainsi, si vous voulez "arrêter tôt" ou annuler autrement les éléments en attente d'une file d'attente d'expédition (peu importe la manière dont ils ont été en cours), vous le faites en partageant un peu d'état avec les blocs en justice qui vous permettent d'annuler. P>
__block BOOL keepGoing = YES;
dispatch_*(someQueue, ^{
if (!keepGoing) return;
if (weAreDoneNow) keepGoing = NO;
}