2010-06-15 9 views
29

Obecnie używam NSThread do buforowania zdjęć w innym wątku.NSThread vs. NSOperationQueue vs. ??? na iPhonie

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

Alternatywnie:

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

Alternatywnie, można użyć NSOperationQueue

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

Czy jest jakiś powód, aby przełączyć się z dala od NSThread? GCD jest czwartą opcją, gdy jest wydany na iPhone'a, ale jeśli nie ma znaczącego wzrostu wydajności, wolałbym trzymać się metod, które działają na większości platform.


oparciu o poradę @ Jon-Eric, poszedłem z NSOperationQueue/NSOperation rozwiązania podklasy. Pracuje bardzo dobrze. Klasa NSOperation jest na tyle elastyczna, że ​​można jej używać z inwokacjami, blokami lub niestandardowymi podklasami, w zależności od potrzeb. Bez względu na to, jak utworzysz swój NSOperation, możesz po prostu rzucić go do kolejki operacji, kiedy będziesz gotowy do uruchomienia. Operacje są zaprojektowane tak, aby działały jako obiekty umieszczane w kolejce lub można je uruchomić jako autonomiczne metody asynchroniczne, jeśli chcesz. Ponieważ możesz łatwo uruchomić swoje niestandardowe metody działania synchronicznie, testowanie jest banalnie łatwe.

Użyłem tej samej techniki w kilku projektach, ponieważ zadałem to pytanie i nie mogłem być bardziej zadowolony ze sposobu, w jaki mój kod i testy są czyste, uporządkowane i szczęśliwie asynchroniczne.

++++++++++ Czy podklasy ponownie

+0

Możesz profilować każdy z nich. To byłby jeden sposób, aby się dowiedzieć. –

+0

Wydajność była złym słowem, podejrzewam, że pod spodem są takie same. Bardziej szukam kogoś, kto ma doświadczenie z dwoma lub więcej z tych metod, aby dać mi kilka porad na temat preferowanego sposobu i dlaczego jest lepszy. – kubi

Odpowiedz

32

Generalnie otrzymasz lepszy przebieg z NSOperationQueue.

Trzy konkretne powody:

  • Możesz zainicjować buforowanie wielu elementów naraz. NSOperationQueue jest na tyle sprytny, że tworzy tylko tyle wątków, ile jest rdzeni, kolejkuje pozostałe operacje. Z NSThread, tworzenie 100 wątków do buforowania 100 obrazów jest prawdopodobnie przesadą i nieco nieefektywne.
  • Możesz anulować operację cacheImage. Realizacja anulowania jest łatwiejsza z NSOperationQueue; większość pracy jest już dla ciebie wykonana.
  • NSOperationQueue może przełączyć się na inteligentniejszą implementację (taką jak Grand Central Dispatch) teraz lub w przyszłości. NSThread jest bardziej prawdopodobne, że zawsze będzie tylko wątkiem systemu operacyjnego.

Bonus:

  • NSOperationQueue ma jakieś inne miłe konstrukty wbudowane, takie jak wyrafinowany sposób uhonorowania priorytetów operacyjnych i zależności.
+0

Zakładając, że nie potrzebujesz dodatków, które zapewnia funkcja NSOperationQueue, dlaczego tworzenie 100 NSThreads jest nieefektywne? A może zakładasz, że jeśli chcesz utworzyć 100 wątków, musisz mieć jakieś gadżety NSOperationQueue? – Tony

+4

@ Tony: Tworzenie wątku jest bardzo kosztowne. http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Multithreading/CreatingThreads/CreatingThreads.html – kubi

5

użyłbym NSOperationQueue. Pod OS 3.2, NSOperationQueue używa wątków pod maską, więc obie metody powinny działać podobnie. Jednak pod Mac OS 10.6, NSOperationQueue wykorzystuje GCD pod maską i ma tę zaletę, że nie ma narzutów oddzielnych wątków. Nie oglądałem dokumentów dla systemu operacyjnego 4, ale podejrzewam, że robi to coś podobnego - w każdym razie, NSOperationQueue może zamienić implementacje, jeśli/kiedy zalety wydajności GCD staną się dostępne dla iPhone'a.