Question NSOperation vs Grand Central Dispatch


J'apprends à propos de la programmation simultanée pour iOS. Jusqu'à présent, j'ai lu à propos de NSOperation/NSOperationQueue et GCD. Quelles sont les raisons d'utiliser NSOperationQueue plus de GCD et vice versa?

Sonne comme les deux GCD et NSOperationQueue abstraire la création explicite de NSThreads de l'utilisateur. Cependant, la relation entre les deux approches n'est pas claire pour moi, donc tout retour à apprécié!


418
2018-04-29 15:24


origine


Réponses:


GCD est une API de bas niveau basée sur C qui permet une utilisation très simple d'un modèle de concurrence basé sur les tâches. NSOperation et NSOperationQueue sont des classes Objective-C qui font une chose similaire. NSOperation a été introduit en premier, mais à partir de 10.6 et iOS 4, NSOperationQueue et les amis sont mis en œuvre en interne en utilisant GCD.

En général, vous devez utiliser le plus haut niveau d'abstraction qui convient à vos besoins. Cela signifie que vous devez généralement utiliser NSOperationQueue au lieu de GCD, sauf si vous avez besoin de faire quelque chose NSOperationQueue ne supporte pas.

Notez que NSOperationQueue n'est pas une version "abaissée" de GCD; en fait, il y a beaucoup de choses que vous pouvez faire très simplement avec NSOperationQueue qui prennent beaucoup de travail avec pure GCD. (Exemples: files d'attente limitées par la bande passante qui n'exécutent que N opérations à la fois; établissement de dépendances entre les opérations. Les deux sont très simples avec NSOperationtrès difficile avec GCD.) Apple a fait le dur travail de tirer parti de GCD pour créer une très belle API conviviale avec NSOperation. Profitez de leur travail, sauf si vous avez une raison de ne pas le faire.

Caveat: D'un autre côté, si vous avez vraiment besoin d'envoyer un bloc, et que vous n'avez besoin d'aucune des fonctionnalités supplémentaires NSOperationQueue fournit, il n'y a rien de mal à utiliser GCD. Assurez-vous simplement que c'est le bon outil pour le travail.


475
2018-04-29 20:16



En ligne avec ma réponse à une question connexe, Je vais être en désaccord avec BJ et suggérer que vous examiniez d'abord GCD sur NSOperation / NSOperationQueue, à moins que ce dernier ne fournisse quelque chose dont vous n'avez pas besoin pour GCD.

Avant GCD, j'ai utilisé beaucoup de NSOperations / NSOperationQueues dans mes applications pour gérer la concurrence. Cependant, depuis que j'ai commencé à utiliser régulièrement GCD, j'ai presque entièrement remplacé NSOperations et NSOperationQueues par des blocs et des files d'attente. Cela est dû à la manière dont j'ai utilisé les deux technologies en pratique et à partir du profilage que j'ai effectué sur ces deux technologies.

Tout d'abord, il existe une quantité non négligeable de surcharge lors de l'utilisation de NSOperations et de NSOperationQueues. Ce sont des objets Cocoa, et ils doivent être alloués et désalloués. Dans une application iOS que j'ai écrite et qui restitue une scène 3D à 60 images par seconde, j'utilisais NSOperations pour encapsuler chaque image rendue. Lorsque je l'ai décrit, la création et la suppression de ces NSOperations représentaient une partie importante des cycles du processeur dans l'application en cours d'exécution et ralentissaient les choses. Je les ai remplacés par des blocs simples et une file d'attente série GCD, et cette surcharge a disparu, ce qui a permis d'améliorer considérablement les performances de rendu. Ce n’était pas le seul endroit où j’avais remarqué que NSOperations ne fonctionnait pas, et j’ai vu cela sur Mac et iOS.

Deuxièmement, il y a une élégance à code d'expédition basé sur un bloc qui est difficile à égaler lors de l'utilisation de NSOperations. Il est incroyablement pratique d'enrouler quelques lignes de code dans un bloc et de l'envoyer sur une file d'attente série ou simultanée, où la création d'un NSOperation ou d'un NSInvocationOperation personnalisé nécessite beaucoup plus de code. Je sais que vous pouvez utiliser un NSBlockOperation, mais vous pourriez tout aussi bien envoyer quelque chose à GCD. Envelopper ce code dans des blocs en ligne avec le traitement associé dans votre application conduit, à mon avis, à une meilleure organisation du code plutôt qu'à des méthodes séparées ou à des NSOperations personnalisées qui encapsulent ces tâches.

NSOperations et NSOperationQueues ont toujours de très bons usages. GCD n'a pas de véritable concept de dépendances, où NSOperationQueues peut mettre en place des graphes de dépendance assez complexes. J'utilise NSOperationQueues pour cela dans une poignée de cas.

Dans l'ensemble, bien que je préconise généralement d'utiliser le plus haut niveau d'abstraction qui accomplit la tâche, c'est un cas où je plaide pour l'API de niveau inférieur de GCD. Parmi les développeurs iOS et Mac dont j'ai parlé à ce sujet, la grande majorité a choisi d'utiliser GCD sur NSOperations à moins qu'ils ne ciblent des versions OS sans support (celles d'avant iOS 4.0 et Snow Leopard).


346
2018-04-30 02:04



GCD est une API de bas niveau basée sur C.
NSOperation et NSOperationQueue sont des classes Objective-C.
NSOperationQueue est objectif C enveloppe sur GCD. Si vous utilisez NSOperation, vous utilisez implicitement Grand Central Dispatch.

GCD avantage sur NSOperation:
je. la mise en oeuvre
Pour GCD la mise en œuvre est très léger
NSOperationQueue est complexe et lourd

NSOperation avantages sur GCD:

je. Contrôle sur le fonctionnement
vous pouvez mettre en pause, annuler, reprendre un NSOperation

ii. Dépendances
vous pouvez configurer une dépendance entre deux NSOperations
L'opération ne démarrera pas tant que toutes ses dépendances ne seront pas retournées.

iii. État d'opération
peut surveiller l'état d'une opération ou d'une file d'attente d'opérations. prêt, en cours d'exécution ou fini

iv. Nombre maximum d'opérations
vous pouvez spécifier le nombre maximal d'opérations en file d'attente pouvant s'exécuter simultanément

Quand aller pour GCD ou NSOperation
quand vous voulez plus de contrôle sur la file d'attente (tout ce qui précède), utilisez NSOperation  et pour les cas simples où vous voulez moins de frais généraux (vous voulez juste faire du travail "en arrière-plan" avec très peu de travail supplémentaire) GCD

ref:
https://cocoacasts.com/choosing-between-nsoperation-and-grand-central-dispatch/ http://iosinfopot.blogspot.in/2015/08/nsthread-vs-gcd-vs-nsoperationqueue.html http://nshipster.com/nsoperation/


56
2017-10-15 21:36



GCD est en effet de niveau inférieur à NSOperationQueue, son principal avantage est que son implémentation est très légère et axée sur les algorithmes et les performances sans verrouillage.

NSOperationQueue fournit des fonctionnalités qui ne sont pas disponibles dans GCD, mais elles ont un coût non négligeable, l'implémentation de NSOperationQueue est complexe et lourde, implique beaucoup de verrouillage et utilise GCD en interne uniquement de manière très minimale.

Si vous avez besoin des fonctionnalités fournies par NSOperationQueue par tous les moyens, utilisez-le, mais si GCD est suffisant pour vos besoins, je vous recommande de l'utiliser directement pour de meilleures performances, des coûts d'UC et d'énergie considérablement réduits.


33
2018-04-30 00:50



Une autre raison de préférer NSOperation à GCD est le mécanisme d'annulation de NSOperation. Par exemple, une application comme 500px qui montre des dizaines de photos, utilisez NSOperation nous pouvons annuler les demandes de cellules d'image invisibles lorsque vous faites défiler la vue de la table ou la collection, cela peut grandement améliorer les performances de l'application et réduire l'empreinte mémoire. GCD ne peut pas facilement supporter cela.

Aussi avec NSOperation, KVO peut être possible.

Ici est un article d'Eschaton qui mérite d'être lu.


32
2018-01-02 08:08



NSQueueOperations et GCD permettent l'exécution de tâches de calcul lourdes en arrière-plan sur des threads séparés en libérant la bande de roulement principale de l'application.

Eh bien, sur la base du post précédent, nous voyons que NSOperations a addDependency pour que vous puissiez mettre en file d'attente vos opérations les unes après les autres de manière séquentielle.

Mais je lis aussi à propos des files d'attente série GCD que vous pouvez créer. Exécutez vos opérations dans la file d'attente en utilisant dispatch_queue_create. Cela permettra d'exécuter un ensemble d'opérations les unes après les autres de manière séquentielle.

Avantages de NSQueueOperation sur GCD:

  1. Il permet d'ajouter des dépendances et vous permet de supprimer les dépendances pour une transaction que vous pouvez exécuter séquentiellement en utilisant la dépendance et pour d'autres transactions en même temps que GCD ne permet pas de courir de cette façon.

  2. Il est facile d'annuler une opération si elle est dans la file d'attente, elle peut être arrêtée si elle est en cours d'exécution.

  3. Vous pouvez définir le nombre maximal d'opérations simultanées.

  4. Vous pouvez suspendre l'opération dans laquelle ils sont placés

  5. Vous pouvez trouver le nombre d'opérations en attente dans la file d'attente.


23
2017-08-14 20:45



GCD est très facile à utiliser - si vous voulez faire quelque chose en arrière-plan, tout ce que vous avez à faire est d'écrire le code et de l'envoyer dans une file d'attente d'arrière-plan. Faire la même chose avec NSOperation, c'est beaucoup de travail supplémentaire.

L'avantage de NSOperation est que (a) vous avez un objet réel auquel vous pouvez envoyer des messages, et (b) que vous pouvez annuler une NSOperation. Ce n'est pas trivial. Vous devez sous-classer NSOperation, vous devez écrire votre code correctement pour que l'annulation et la fin correcte d'une tâche fonctionnent correctement. Donc, pour les choses simples, vous utilisez GCD, et pour les choses plus compliquées, vous créez une sous-classe de NSOperation. (Il existe des sous-classes NSInvocationOperation et NSBlockOperation, mais tout ce qu'elles font est plus facile avec GCD, donc il n'y a pas de bonne raison de les utiliser).


5
2017-08-06 00:41



Eh bien, NSOperations est simplement une API construite au-dessus de Grand Central Dispatch. Ainsi, lorsque vous utilisez NSOperations, vous utilisez toujours Grand Central Dispatch. C'est juste que NSOperations vous donne quelques fonctionnalités fantaisie que vous pourriez aimer. Vous pouvez rendre certaines opérations dépendantes d'autres opérations, réorganiser les files d'attente après les éléments sumbit, et d'autres choses comme ça. En fait, ImageGrabber utilise déjà NSOperations et les files d'attente d'opération! ASIHTTPRequest les utilise sous le capot, et vous pouvez configurer la file d'attente d'opérations qu'il utilise pour un comportement différent si vous le souhaitez. Alors, que devriez-vous utiliser? Celui qui a du sens pour votre application. Pour cette application, c'est assez simple, donc nous avons utilisé directement Grand Central Dispatch, pas besoin de fonctionnalités sophistiquées de NSOperation. Mais si vous en avez besoin pour votre application, n'hésitez pas à l'utiliser!


3
2017-08-13 11:40