2010-06-15 55 views
29

Actuellement j'utilise NSThread pour mettre en cache des images dans un autre fil.NSThread vs NSOperationQueue vs. sur l'iPhone

[NSThread detachNewThreadSelector:@selector(cacheImage:) toTarget:self withObject:image]; 

Alternativement:

[self performSelectorInBackground:@selector(cacheImage:) withObject:image]; 

Sinon, je peux utiliser un NSOperationQueue

NSInvocationOperation *invOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(cacheImage:) object:image]; 
NSOperationQueue *opQueue = [[NSOperationQueue alloc] init]; 
[opQueue addOperation:invOperation]; 

Y at-il raison de se détourner de NSThread? GCD est une 4ème option quand il est sorti pour l'iPhone, mais à moins d'un gain de performance significatif, je préfère rester avec des méthodes qui fonctionnent sur la plupart des plateformes.


Basé sur @ conseils de Jon-Eric, je suis allé avec une solution de sous-classe NSOperationQueue/NSOperation. Il fonctionne très bien. La classe NSOperation est assez flexible pour que vous puissiez l'utiliser avec des invocations, des blocs ou des sous-classes personnalisées, selon vos besoins. Peu importe comment vous créez votre NSOperation, vous pouvez simplement le jeter dans une file d'attente d'opérations lorsque vous êtes prêt à l'exécuter. Les opérations sont conçues pour fonctionner en tant qu'objets que vous mettez dans une file d'attente ou vous pouvez les exécuter en tant que méthodes asynchrones autonomes, si vous le souhaitez. Puisque vous pouvez facilement exécuter vos méthodes d'opération personnalisées de manière synchrone, le test est trivialement facile. J'ai utilisé cette même technique dans une poignée de projets depuis que j'ai posé cette question et je ne pourrais pas être plus heureux de la façon dont il garde mon code et mes tests propres, organisés et heureusement asynchrones.

A ++++++++++ Ne serait-nouveau sous-classe

+0

Vous pouvez profiler chacun d'entre eux. Ce serait un moyen de le savoir. –

+0

Performance était le mauvais mot, je soupçonne qu'ils sont tous les mêmes en dessous. Je suis plus à la recherche de quelqu'un qui a l'expérience avec deux ou plusieurs de ces méthodes pour me donner quelques conseils sur la façon préférée et pourquoi c'est mieux. – kubi

Répondre

32

En général, vous obtiendrez un meilleur kilométrage avec NSOperationQueue.

Trois raisons spécifiques:

  • Vous pouvez vouloir lancer la mise en cache de nombreux éléments à la fois. NSOperationQueue est assez intelligent pour créer seulement autant de threads qu'il y a de cœurs, mettant en file d'attente les opérations restantes. Avec NSThread, la création de 100 threads pour mettre en cache 100 images est probablement exagérée et plutôt inefficace.
  • Vous souhaiterez peut-être annuler l'opération cacheImage. La mise en œuvre de l'annulation est plus facile avec NSOperationQueue; la plupart du travail est déjà fait pour vous.
  • NSOperationQueue est libre de passer à une implémentation plus intelligente (comme Grand Central Dispatch) maintenant ou dans le futur. NSThread est plus susceptible de toujours être juste un thread de système d'exploitation.

Bonus:

  • NSOperationQueue a d'autres constructions belles intégré, comme un moyen sophistiqué d'honorer les priorités de fonctionnement et les dépendances.
+0

En supposant que vous n'avez pas besoin des extras fournis par NSOperationQueue, pourquoi la création de 100 NSThreads est-elle inefficace? Ou êtes-vous en supposant que si 100 threads doivent être créés, il doit y avoir un besoin de certains goodies NSOperationQueue? – Tony

+4

@Tony: Créer un thread est très coûteux. http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Multithreading/CreatingThreads/CreatingThreads.html – kubi

5

J'utiliser NSOperationQueue. Sous OS 3.2, NSOperationQueue utilise des threads sous le capot, de sorte que les deux méthodes doivent fonctionner de manière similaire. Cependant, sous Mac OS 10.6, NSOperationQueue utilise GCD sous le capot et a donc l'avantage de ne pas avoir le surdébit de fils séparés. Je n'ai pas regardé les docs pour OS 4, mais je suppose qu'il fait quelque chose de similaire - en tout cas, NSOperationQueue pourrait échanger des implémentations si/quand les avantages de performance de GCD deviennent disponibles pour l'iPhone.