web-dev-qa-db-fra.com

NSOperation vs Grand Central Dispatch

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

On dirait que GCD et NSOperationQueue abstiennent la création explicite de NSThreads par l'utilisateur. Cependant, la relation entre les deux approches n'est pas claire pour moi, donc tout retour d'information à apprécier!

451
SundayMonday

GCD est une API de bas niveau basée sur C qui permet une utilisation très simple d'un modèle de simultanéité basé sur des tâches. NSOperation et NSOperationQueue sont des classes Objective-C qui font la même chose. NSOperation a été introduit en premier, mais à partir de 10.6 et iOS 4, NSOperationQueue et ses amis sont implémentés en interne à l'aide de GCD.

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

Notez que NSOperationQueue n'est pas une version "simplifiée" de GCD; En fait, il y a beaucoup de choses que vous pouvez faire très simplement avec NSOperationQueue qui demandent beaucoup de travail avec pure GCD. (Exemples: files d'attente soumises à des contraintes de bande passante ne exécutant que N opérations à la fois; établissement de dépendances entre opérations. Les deux très simples avec NSOperation, très difficiles avec GCD.) Apple a effectué le travail difficile nécessaire pour utiliser GCD 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 fournies par NSOperationQueue, l'utilisation de GCD n'est pas un problème. Assurez-vous simplement que c'est le bon outil pour le travail.

509
BJ Homer

Conformément à ma réponse à une question connexe , je ne suis pas d'accord avec BJ et je vous suggère de commencer par examiner GCD via NSOperation/NSOperationQueue, à moins que ce dernier ne fournisse quelque chose dont vous avez besoin et que GCD n'a pas.

Avant GCD, j’utilisais beaucoup de NSOperations/NSOperationQueues dans mes applications pour gérer les accès simultanés. 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 vient de la manière dont j'ai utilisé les deux technologies dans la pratique et du profilage que j'ai effectué sur celles-ci.

Premièrement, l'utilisation de NSOperations et de NSOperationQueues entraîne des frais généraux non négligeables. Ce sont des objets de cacao, et ils doivent être alloués et désalloués. Dans une application iOS que j'ai écrite et qui rend une scène 3D à 60 images par seconde, j'utilisais NSOperations pour encapsuler chaque image rendue. Lorsque j'ai décrit cette situation, la création et le démantèlement de ces opérations NSO ont représenté une partie importante des cycles de processeur dans l'application en cours d'exécution et ont ralenti les choses. J'ai remplacé ceux-ci par des blocs simples et une file d'attente série GCD, et cette surcharge a disparu, ce qui a sensiblement amélioré les performances de rendu. Ce n’est pas le seul endroit où j’ai remarqué des frais généraux liés à l’utilisation de NSOperations, et je l’ai vu à la fois sur Mac et iOS.

Deuxièmement, le code de répartition basé sur les blocs présente une élégance difficile à égaler lors de l'utilisation de NSOperations. Il est extrêmement pratique de regrouper quelques lignes de code dans un bloc et de le répartir pour qu'il soit exécuté sur une file d'attente en série ou simultanée. La création d'une NSOperation ou d'une NSInvocationOperation personnalisée à cette fin nécessite beaucoup plus de code de support. Je sais que vous pouvez utiliser une opération NSBlockOperation, mais vous pourriez aussi bien envoyer quelque chose à GCD à ce moment-là. Envelopper ce code dans des blocs en ligne avec les traitements correspondants dans votre application conduit, à mon avis, à une meilleure organisation du code que d'avoir des méthodes séparées ou des opérations NSO personnalisées qui encapsulent ces tâches.

NSOperations et NSOperationQueues ont encore de très bonnes utilisations. GCD n'a pas de concept réel de dépendances, où NSOperationQueues peut configurer 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 permettant d’accomplir cette tâche, c’est un cas où j’arguais pour l’API de niveau inférieur de GCD. Parmi les développeurs iOS et Mac avec lesquels j'ai discuté, la grande majorité d'entre eux choisissent d'utiliser GCD au lieu de NSOperations, à moins qu'ils ne ciblent des versions de système d'exploitation dépourvues de support (versions antérieures à iOS 4.0 et Snow Leopard).

364
Brad Larson

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

Avantage GCD par rapport à NSOperation:
i. la mise en oeuvre
Pour GCD la mise en oeuvre est très légère
NSOperationQueue est complexe et lourd

Avantages de NSOperation par rapport à GCD:

i. Contrôle en fonctionnement
vous pouvez mettre en pause, annuler, reprendre une NSOperation

ii. Dépendances
vous pouvez configurer une dépendance entre deux NSOperations
L’opération ne commencera pas tant que toutes ses dépendances ne seront pas vraies.

iii. Etat de fonctionnement
peut surveiller l’état d’une opération ou d’une file d’opérations. prêt, en cours d'exécution ou terminé

iv. Nombre maximum d'opération
vous pouvez spécifier le nombre maximum d'opérations en file d'attente pouvant être exécutées simultanément

Quand choisir GCD ou NSOperation
lorsque vous souhaitez davantage de contrôle sur la file d'attente (tout ce qui est mentionné ci-dessus), utilisez NSOperation et pour les cas simples où vous souhaitez moins de temps système (vous souhaitez simplement effectuer un travail "en arrière-plan" avec très peu de travail supplémentaire ) utilise GCD

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

89
Sangram Shivankar

Une autre raison de préférer NSOperation à GCD est le mécanisme d'annulation de NSOperation. Par exemple, une application telle que 500 pixels montrant des dizaines de photos, utilisez NSOperation pour annuler les demandes de cellules d'image invisibles lorsque vous faites défiler la vue de tableau ou de collection, ce qui peut considérablement améliorer les performances de l'application et réduire l'encombrement de la 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.

34
evanchin

GCD est en effet de niveau inférieur à NSOperationQueue, son principal avantage est que sa mise en œuvre est très légère et axée sur des algorithmes et des performances sans verrouillage.

NSOperationQueue fournit des installations 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 verrouillages et utilise GCD en interne de manière très minimale.

Si vous avez absolument besoin des fonctionnalités fournies par NSOperationQueue, utilisez-les, mais si GCD suffit à vos besoins, je vous recommande de les utiliser directement pour obtenir de meilleures performances, des coûts de processeur et de puissance considérablement réduits et davantage de flexibilité.

33
das

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

D'après l'article précédent, nous constatons que NSOperations a addDependency afin que vous puissiez mettre en file d'attente votre opération l'une après l'autre.

Mais j'ai aussi lu des informations sur les files d'attente série GCD que vous pouvez créer, exécutez vos opérations dans la file d'attente à l'aide de dispatch_queue_create. Cela permettra d'exécuter une série d'opérations l'une après l'autre de manière séquentielle.

Avantages de NSQueueOperation par rapport à GCD:

  1. Il permet d'ajouter une dépendance et vous permet de supprimer la dépendance afin que vous puissiez exécuter une dépendance séquentielle à l'aide de la dépendance et que d'autres transactions s'exécutent simultanément alors que GCD n'autorise pas l'exécution de cette manière.

  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 qu'ils sont en file d'attente

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

23
Shashi3456643

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

L’avantage de NSOperation est que (a) vous pouvez envoyer un message à un objet réel, et (b) que vous pouvez annuler une opération 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 des choses simples, vous utilisez GCD et pour des choses plus complexes, 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 à faire avec GCD, il n'y a donc aucune bonne raison de les utiliser).

5
gnasher729

NSOperations est simplement une API construite sur Grand Dispatch Grand Central. Ainsi, lorsque vous utilisez NSOperations, vous utilisez toujours Grand Dispatch Grand Central. C'est simplement que NSOperations vous offre des fonctionnalités sophistiquées qui pourraient vous intéresser. Vous pouvez rendre certaines opérations dépendant d'autres opérations, réorganiser les files d'attente après avoir ajouté des éléments, etc. En fait, ImageGrabber utilise déjà NSOperations et les files d'attente! ASIHTTPRequest les utilise sous le capot et vous pouvez configurer la file d’opérations qu’il utilise pour un comportement différent si vous le souhaitez. Alors, lequel devriez-vous utiliser? Selon ce qui convient à votre application. Pour cette application, c'est assez simple, nous avons donc utilisé directement Grand Central Dispatch, sans avoir besoin des fonctionnalités sophistiquées de NSOperation. Mais si vous en avez besoin pour votre application, n'hésitez pas à l'utiliser!

3
Ankul Gaur