Quels sont les différents moyens pour appeler ma méthode sur un thread séparé?
J'ai des données méthode de calcul (let it be "myMethod:"), et je souhaite passer l'appel vers un autre thread parce que je ne veux pas bloquer mon INTERFACE principale fonctionnalité. Donc, a commencé à faire quelques recherches sur la façon d'appeler ma méthode sur un autre thread. Autant que je le vois, actuellement, il ya beaucoup de façons différentes de le faire. En voici une liste:
a) à l'aide de pure threads (disponible depuis iOS 2.0):
[NSThread detachNewThreadSelector:@selector(myMethod:) toTarget:self withObject:_myParamsArray];
b) à l'aide d'un simple raccourci (disponible depuis iOS 2.0). Disponible à partir hérité de NSObject mais la méthode appartient à NSThread classe trop:
[self performSelectorInBackground:@selector(myMethod:) withObject:_myParamsArray];
c) en utilisant une nouvelle approche de Grand Central Dispatch des files d'attente (disponible depuis iOS 4.0):
dispatch_async(dispatch_get_global_queue(0, 0),
^ {
[self myMethod:_myParamsArray];
});
d) d'une certaine manière, l'utilisation de certaines classes comme NSOperation, NSBlockOperation ou NSOperationQueue, mais pas exactement de quelle façon le faire (par exemple, serait appréciée)
Actuellement, j'ai utilisé de cas "b" mais curieux à propos des avantages et des inconvénients, et à d'autres suggestions sur qui.
Mise à JOUR: e) a également trouvé un autre moyen pour effectuer similaire filetage de trucs Exécuter des boucles. Voici un extrait de pomme docs:
Une course boucle est une boucle de traitement des événements que vous utilisez pour le travail de programme et de coordonner la réception des événements. Le but de l'exécution de la boucle est de garder votre fil occupé quand il y a du travail à faire et de mettre votre fil de dormir quand il n'y a aucun.
À mon humble avis, plus ou moins de votre affaire à la même tâche - comment appeler votre méthode sur un thread séparé pour son opération asynchrone.
UPDATE2: Déjà eu une certaine expérience avec NSInvocationOperation et NSOperationQueue et à mon avis c'est assez pratique. Selon Apple docs, PGCD et NSOperations sont un moyen privilégié pour la mise en œuvre de multithreading. Et aussi, NSOperations s'exécute sur PGCD de départ à partir de iOS 4.0. En bref, vous instanciez NSIvocationOperation (comme un appel à votre méthode) puis instancier NSOperationQueue et ajouter de l'invocation à la file d'attente. NSOperationQueue est la chose la plus intelligente assez, vous pouvez instancier plusieurs NSIvocationOperation objets (emballage de vos appels de méthode) et à NSOperationQueue. Le repos est assuré. NSOperationQueue détermine la quantité de fils parallèles, il faut effectuer les appels (NSInvocationOperation) et s'en occupe pour vous. Il peut exécuter du premier appel sur Un thread, puis la deuxième sur le fil B, troisième sur le fil C-et-vient sur le fil B, de sorte que vous ne avez pas à vous inquiéter à ce sujet. Mais si vous le souhaitez, vous pouvez dire comment max de threads NSOperationQueue pouvez utiliser pour effectuer des appels (par exemple 1), mais je n'ai pas besoin de cela. Par défaut, toutes les tâches sont effectuées sur d'autres que le thread principal, afin que le fonctionnement des files d'attente asynchrone par défaut. Aussi, si vous souhaitez effectuer vos appels de méthode (chacun enveloppé dans distincte NSInvocationOperation) dans le cadre strict de la file d'attente, alors vous pouvez ajouter des dépendances et ainsi de NSOperationQueue permettra de préserver l'ordre d'appel de méthode. Voici un exemple:
//wrap your method call into NSInvocationOperation object
NSInvocationOperation *currentOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(yourMethodCall) object:nil];
//_sharedOperationQueue is a shared NSOperationQueue
//get all executing operations from the queue and get the last operation
_lastOperation = [[_sharedOperationQueue operations] lastObject];
//check if _lastOperation is not nil
if (_lastOperation) {
//if not then add dependency, so the calls would be performed in a queue
[currentOperation addDependency:_lastOperation];
}
//say - execute my method (operation)
[_sharedOperationQueue addOperation:currentOperation];
_lastOperation = currentOperation; //mark as last operation for adding dependency to the next operation
//the queue will retain invocation operation so you will release
[currentOperation release];
..... you can create another NSInvocationOperation and add it to the queue....
Comme pour RUNLOOPs, encore, parfois, vous ferez face à eux, par exemple lors du lancement/ordonnancement d'une minuterie, ou de faire NSURL connexions. À mon humble avis, un runloop pourrait être comparé à une file d'attente de tâches exécutées sur un seul thread. À mon humble avis un runloop est un pointeur vers un thread qui fonctionne comme une file d'attente: il a des tâches qui pourraient jeter les événements et ils seront placés à la fin de la file d'attente dans ce thread. Par défaut, toutes les tâches dans votre application de fonctionner dans un seul runloop - dans un seul thread. Je dis que c'est un pointeur, car lorsque votre application génère des événements de l'application doit savoir où mettre cet événement (événement tactile ou un autre délégué de rappel) pour l'exécution. Bien sûr, vous devriez lire à propos de runloops pour de plus amples informations, car ce ne sont que mes pensées.
Vous devez vous connecter pour publier un commentaire.
Habituellement, vous préférez le PGCD approche.
C'est plus simple quand il s'agit de la synchronisation/verrouillage de pure threads (NSThread - pthread), et il peut être plus précis dans une perspective de performance.
Lors de l'utilisation de pure threads, le problème est que vous pouvez avoir des problèmes de performance, en fonction du nombre de cœurs disponibles/processeurs.
Par exemple, si vous avez un seul noyau, créant de nombreux threads peuvent ralentir votre application, parce que le CPU va passer la plupart de son temps de commutation à partir d'un thread à l'autre, d'économiser la pile, registres, etc.
D'autre part, si vous avez beaucoup de cœurs disponibles, il peut être sympa de créer un grand nombre de threads différents.
C'est là que PGCD permet, comme il le gère pour vous. Il permettra de créer le nombre de threads, basée sur les ressources système disponibles, afin de garantir une utilisation optimale, et de planifier vos actions de manière appropriée.
Toutefois, pour cette raison, les tâches lancé avec PGCD peut-être pas en temps réel.
Donc, si vous avez VRAIMENT besoin qu'un décollement de la tâche s'exécute immédiatement, l'utilisation explicite de threads. Sinon, utilisez le PGCD.
Espérons que cela vous aidera : )
MODIFIER
Une remarque à propos de
performSelectorInBackground
: il crée simplement un nouveau thread. Donc, il n'y a fondamentalement pas de différence avec le NSThread approche.EDIT 2
NSOperation liés choses sont un peu différentes. Sur Mac OS X, ils sont mis en œuvre en utilisant le PGCD depuis la version 10.6. Les versions précédentes utilise des threads.
Sur iOS, ils sont mis en œuvre à l'aide de threads seulement.
Référence
Tout cela est très bien expliqué dans le La Simultanéité Guide De Programmation. Il aborde le PGCD de fil et d'approches, avec beaucoup de détails sur les utilisations et les implémentations.
Si vous ne l'avez pas lu, vous devriez jeter un oeil.
Ici est une mise à jour de réponse à cette vieille question. NSOperations sont mis en œuvre avec libdispatch pour les deux macos et ios maintenant. Ils l'ont été pendant un certain temps. La meilleure façon d'appeler à un autre thread est avec l'un de libdispatch ou NSOperations. L'idée principale est de garder à l'esprit est la "Qualité de Service", ou "QOS". La QOS est quelque chose d'affecté à un thread, et quand vous pouvez l'affecter à un message de la file d'attente, et NSOperationQueue, ou un NSOperation, vous êtes essentiellement en disant: "je veux que cela s'exécuter sur un fil avec cette QOS affectée." Le cas particulier est le thread principal.
Il y a encore de certains cas d'utiliser NSThread, mais je n'ai pas eu le tout pour un long moment.