J'apprends la programmation simultanée pour iOS. Jusqu'à présent, j'ai lu sur NSOperation
/NSOperationQueue
et GCD
. Quelles sont les raisons d'utiliser NSOperationQueue
Over GCD
et vice versa?
Sonne comme les deux GCD
et NSOperationQueue
résume la création explicite NSThreads
de l'utilisateur. Cependant, la relation entre les deux approches n'est pas claire pour moi, donc toute rétroaction est appréciée!
ios
concurrency
grand-central-dispatch
nsoperation
nsoperationqueue
Dimanche Lundi
la source
la source
Réponses:
GCD
est une API basée sur C de bas niveau qui permet une utilisation très simple d'un modèle de concurrence basé sur les tâches.NSOperation
etNSOperationQueue
sont des classes Objective-C qui font une chose similaire.NSOperation
a été introduit en premier, mais à partir de 10,5 et iOS 2 ,NSOperationQueue
et les amis sont implémentés en interne à l'aideGCD
.En général, vous devez utiliser le niveau d'abstraction le plus élevé qui convient à vos besoins. Cela signifie que vous devez généralement utiliser
NSOperationQueue
au lieu deGCD
, sauf si vous devez faire quelque chose quiNSOperationQueue
ne prend pas en charge.Notez qu'il
NSOperationQueue
ne s'agit pas d'une version "simplifiée" de GCD; en fait, il y a beaucoup de choses que vous pouvez faire très simplement avecNSOperationQueue
qui demandent beaucoup de travail avec pureGCD
. (Exemples: files d'attente à bande passante limitée qui n'exécutent que N opérations à la fois; établissement de dépendances entre les opérations. Les deux sont très simples avecNSOperation
, très difficiles avecGCD
.) Apple a fait le travail acharné de tirer parti de GCD pour créer une très jolie API conviviale avecNSOperation
. Profitez de leur travail, sauf si vous avez une raison de ne pas le faire.Mise en garde : 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
fournies, il n'y a rien de mal à utiliser GCD. Assurez-vous simplement que c'est le bon outil pour le travail.la source
Conformément à ma réponse à une question connexe , je vais être en désaccord avec BJ et vous suggérer d'abord de regarder GCD sur NSOperation / NSOperationQueue, à moins que ce dernier ne fournisse quelque chose dont vous avez besoin que GCD ne fait pas.
Avant GCD, j'utilisais beaucoup de NSOperations / NSOperationQueues dans mes applications pour gérer la concurrence. Cependant, depuis que j'ai commencé à utiliser GCD régulièrement, j'ai presque entièrement remplacé NSOperations et NSOperationQueues par des blocs et des files d'attente de répartition. Cela vient de la façon dont j'ai utilisé les deux technologies dans la pratique et du profilage que j'ai effectué sur elles.
Tout d'abord, il y a une quantité non négligeable de frais généraux lors de l'utilisation de NSOperations et NSOperationQueues. Ce sont des objets Cocoa, et ils doivent être alloués et désalloués. Dans une application iOS que j'ai écrite qui rend une scène 3D à 60 FPS, j'utilisais NSOperations pour encapsuler chaque image rendue. Lorsque j'ai présenté ce profil, 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. J'ai remplacé ceux-ci par de simples blocs et une file d'attente série GCD, et cette surcharge a disparu, conduisant à des performances de rendu sensiblement meilleures. Ce n'était pas le seul endroit où j'ai remarqué des frais généraux en utilisant NSOperations, et je l'ai vu sur Mac et iOS.
Deuxièmement, le code de répartition basé sur des blocs est d'une élégance difficile à égaler lors de l'utilisation de NSOperations. Il est si incroyablement pratique d'envelopper quelques lignes de code dans un bloc et de le distribuer pour qu'il soit exécuté sur une file d'attente série ou simultanée, où la création d'une NSOperation ou NSInvocationOperation personnalisée pour ce faire nécessite beaucoup plus de code de prise en charge. Je sais que vous pouvez utiliser un NSBlockOperation, mais vous pourriez 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 que d'avoir des méthodes distinctes ou des NSOperations personnalisées qui encapsulent ces tâches.
NSOperations et NSOperationQueues ont toujours de très bonnes utilisations. GCD n'a pas de véritable concept de dépendances, où NSOperationQueues peut configurer des graphiques de dépendance assez complexes. J'utilise NSOperationQueues pour cela dans une poignée de cas.
Dans l'ensemble, alors que je préconise généralement d'utiliser le niveau d'abstraction le plus élevé 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 avec lesquels j'ai parlé de cela, la grande majorité choisit d'utiliser GCD sur NSOperations à moins qu'ils ne ciblent des versions de système d'exploitation sans prise en charge (celles avant iOS 4.0 et Snow Leopard).
la source
GCD
est une API basique basée sur C.NSOperation
etNSOperationQueue
sont des classes Objective-C.NSOperationQueue
est wrapper objectif C surGCD
. Si vous utilisez NSOperation, vous utilisez implicitement Grand Central Dispatch.Avantage GCD par rapport à NSOperation:
i. mise en œuvre
Pour la
GCD
mise en œuvre est très légerNSOperationQueue
est complexe et lourdAvantages de NSOperation par rapport à GCD:
je. Contrôle du fonctionnement,
vous pouvez suspendre, annuler, reprendre un
NSOperation
ii. Les dépendances que
vous pouvez configurer une dépendance entre deux
NSOperations
opérations ne seront pas démarrées tant que toutes ses dépendances ne seront pas vérifiées pour terminées.
iii. L'état de fonctionnement
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 terminé
iv. Nombre
maximal d'opérations, vous pouvez spécifier le nombre maximal d'opérations en file d'attente pouvant s'exécuter simultanément
Quand y aller
GCD
ouNSOperation
quand vous voulez plus de contrôle sur l'utilisation de la file d'attente (tous mentionnés ci-dessus)
NSOperation
et pour les cas simples où vous voulez moins de surcharge (vous voulez juste faire du travail "en arrière-plan" avec très peu de travail supplémentaire)GCD
réf:
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/
la source
Une autre raison de préférer NSOperation à GCD est le mécanisme d'annulation de NSOperation. Par exemple, une application comme 500 pixels qui affiche des dizaines de photos, utilise NSOperation, nous pouvons annuler les demandes de cellules d'image invisibles lorsque nous faisons défiler la vue de tableau ou la vue de collection, cela peut considérablement 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.
Voici un article d'Eschaton qui mérite d'être lu.
la source
NSOperation
, carNSURLSessionTask.cancel
etNSURLSession.invalidateAndCancel
fournissez cette fonctionnalité. En général,NSURLSession
fournit certaines des fonctionnalités d'unNSOperationQueue
, commeNSURLSessionTask
fournit certaines des fonctionnalités d'unNSOperation
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, la mise en œuvre 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 que les installations fournies par NSOperationQueue l'utilisent par tous les moyens, mais si GCD est suffisant pour vos besoins, je recommanderais de l'utiliser directement pour de meilleures performances, des coûts de processeur et d'alimentation considérablement inférieurs et plus de flexibilité.
la source
NSQueueOperations et GCD permettent d'exécuter une tâche de calcul lourde en arrière-plan sur des threads distincts en libérant la bande de roulement principale de l'application d'interface utilisateur.
Eh bien, sur la base du post précédent, nous voyons que NSOperations a addDependency afin que vous puissiez mettre votre opération en file d'attente l'une après l'autre de manière séquentielle.
Mais j'ai également lu 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 un ensemble d'opérations les unes après les autres de manière séquentielle.
Avantages de NSQueueOperation par rapport à GCD:
Il permet d'ajouter des dépendances et vous permet de supprimer les dépendances. Ainsi, pour une transaction, vous pouvez exécuter séquentiellement en utilisant la dépendance et pour les autres transactions exécutées simultanément tandis que GCD ne permet pas de s'exécuter de cette façon.
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.
Vous pouvez définir le nombre maximal d'opérations simultanées.
Vous pouvez suspendre le fonctionnement qu'ils sont en file d'attente
Vous pouvez trouver le nombre d'opérations en attente dans la file d'attente.
la source
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 en arrière-plan. Faire la même chose avec NSOperation représente 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 anodin. 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 à faire avec GCD, il n'y a donc aucune bonne raison de les utiliser).
la source
Eh bien, NSOperations est simplement une API construite au-dessus de Grand Central Dispatch. Donc, lorsque vous utilisez NSOperations, vous utilisez vraiment toujours Grand Central Dispatch. C'est juste que NSOperations vous offre des fonctionnalités fantaisistes qui pourraient vous plaire. Vous pouvez rendre certaines opérations dépendantes 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 d'opérations! 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 devez-vous utiliser? Selon ce qui est logique pour votre application. Pour cette application, c'est assez simple, nous avons donc utilisé directement Grand Central Dispatch, pas besoin des fonctionnalités sophistiquées de NSOperation. Mais si vous en avez besoin pour votre application, n'hésitez pas à l'utiliser!
la source