NSOperation vs Grand Central Dispatch

Uczę się programowania współbieżnego dla iOS. Do tej pory czytałem o NSOperation/NSOperationQueue oraz GCD. jakie są powody używania NSOperationQueue przez GCD i vice versa?

Brzmi jak zarówno GCD, jak i NSOperationQueue abstrakcyjne oddzielenie jawnego tworzenia NSThreads od użytkownika. Jednak związek między tymi dwoma podejściami nie jest dla mnie jasny, więc wszelkie opinie docenione!

Author: SundayMonday, 2012-04-29

8 answers

GCD jest niskopoziomowym API C, które umożliwia bardzo proste korzystanie z modelu współbieżności opartego na zadaniach. NSOperation i NSOperationQueue są klasami Objective-C, które robią podobne rzeczy. W wersji 10.6 i iOS 4, NSOperationQueue i przyjaciele są wewnętrznie zaimplementowane przy użyciu GCD.

Ogólnie rzecz biorąc, powinieneś używać najwyższego poziomu abstrakcji, który odpowiada twoim potrzebom. Oznacza to, że zazwyczaj należy używać NSOperationQueue zamiast GCD, chyba że trzeba zrobić coś, co NSOperationQueue nie wsparcie.

Zauważ, że NSOperationQueue nie jest "tępą" wersją GCD; w rzeczywistości jest wiele rzeczy, które możesz zrobić bardzo prosto z NSOperationQueue, które wymagają dużo pracy z czystym GCD. (Przykłady: kolejki o ograniczonej przepustowości, które uruchamiają tylko N operacji na raz; ustalanie zależności między operacjami. Oba bardzo proste z NSOperation, bardzo trudne z GCD.) Apple wykonało ciężką pracę polegającą na wykorzystaniu GCD do stworzenia bardzo ładnego, przyjaznego obiektowi API za pomocą NSOperation. Skorzystaj z ich pracy chyba, że masz powód.

Zastrzeżenie : Z drugiej strony, jeśli naprawdę musisz wysłać blok i nie potrzebujesz żadnej dodatkowej funkcjonalności, która zapewnia NSOperationQueue, nie ma nic złego w używaniu GCD. Upewnij się tylko, że to odpowiednie narzędzie do pracy.

 481
Author: BJ Homer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-10 19:40:37

Zgodnie z moja odpowiedź na powiązane pytanie , zamierzam się nie zgodzić z BJ i sugeruję, abyś najpierw spojrzał na GCD nad NSOperation / NSOperationQueue, chyba że ta ostatnia zapewnia coś, czego potrzebujesz, a GCD nie.

Przed GCD używałem wielu NSOperations / NSOperationQueues w moich aplikacjach do zarządzania współbieżnością. Jednak odkąd zacząłem regularnie używać GCD, prawie całkowicie zastąpiłem nsoperations i NSOperationQueues blokami i wysyłką kolejki. Wynika to z tego, jak wykorzystałem obie technologie w praktyce, oraz z profilowania, które na nich wykonałem.

Po pierwsze, istnieje nietrywialna ilość narzutu podczas korzystania z NSOperations i NSOperationQueues. Są to obiekty kakao, które muszą zostać przydzielone i rozdzielone. W aplikacji na iOS, którą napisałem, która renderuje scenę 3D przy 60 FPS, używałem NSOperations do hermetyzacji każdej renderowanej klatki. Kiedy to opisałem, stworzenie i rozpacz tych NSOperations stanowiło znaczną część cykli procesora w uruchomionej aplikacji i spowalniało proces. Zastąpiłem je prostymi blokami i kolejką szeregową GCD, a to zniknęło, co doprowadziło do zauważalnie lepszej wydajności renderowania. To nie było jedyne miejsce, w którym zauważyłem narzuty z korzystania z NSOperations, i widziałem to zarówno na Macu, jak i iOS.

Po drugie, jest elegancja kodu wysyłkowego opartego na blokach, który jest trudny do dopasowania przy użyciu NSOperations. Jest to tak niezwykle wygodne, aby owinąć kilka linii kodu w bloku i wysłać go do wykonania w kolejce szeregowej lub równoległej, gdzie tworzenie niestandardowego NSOperation lub NSInvocationOperation w tym celu wymaga znacznie więcej kodu wspierającego. Wiem, że możesz użyć NSBlockOperation, ale równie dobrze możesz wysłać coś do GCD. Owijanie tego kodu W Bloki inline z powiązanym przetwarzaniem w Twojej aplikacji prowadzi moim zdaniem do lepszej organizacji kodu niż posiadające oddzielne metody lub niestandardowe NSOperations, które zawierają te zadania.

Nsoperationsqueues i nsoperationqueues nadal mają bardzo dobre zastosowania. GCD nie ma realnego pojęcia zależności, gdzie NSOperationQueues może ustawić dość złożone wykresy zależności. Używam NSOperationQueues do tego w kilku przypadkach.

Ogólnie rzecz biorąc, podczas gdy Zwykle opowiadam się za używaniem najwyższego poziomu abstrakcji, który spełnia zadanie, jest to jeden przypadek, w którym argumentuję za niższym poziomem API GCD. Wśród programistów iOS i Mac, z którymi rozmawiałem na ten temat, zdecydowana większość decyduje się na użycie GCD nad NSOperations, chyba że są one ukierunkowane na wersje systemu operacyjnego bez wsparcia dla niego (te przed iOS 4.0 i Snow Leopard).

 348
Author: Brad Larson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 10:31:35

GCD jest niskopoziomowym API opartym na C.
NSOperation i NSOperationQueue są klasami Objective-C.
NSOperationQueue jest objective C wrapper over GCD. Jeśli używasz NSOperation, to domyślnie używasz Grand Central Dispatch.

Przewaga GCD nad NSOperation:
i. implementacja
Dla GCD implementacja jest bardzo lekka
NSOperationQueue jest złożony i ciężki

Nsoperation advantages over GCD:

i. Kontrola Działania
możesz wstrzymać, anulować, wznowić NSOperation

ii. zależności
możesz ustawić zależność pomiędzy dwoma NSOperations
operacja nie rozpocznie się, dopóki wszystkie jej zależności nie zwrócą true dla zakończonej.

iii. stan działania
może monitorować stan operacji lub kolejki operacji. gotowe, gotowe lub gotowe

iv. Maksymalna liczba operacji
możesz określić maksymalną liczbę operacje w kolejce, które mogą być uruchamiane jednocześnie

Kiedy wybrać GCD LUB NSOperation
jeśli chcesz mieć większą kontrolę nad kolejką (wszystkie wyżej wymienione) użyj NSOperation i w prostych przypadkach, w których potrzebujesz mniej kosztów (po prostu chcesz wykonać jakąś pracę "w tle" z bardzo małą pracą dodatkową) użyj GCD

Ref:
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/

 61
Author: Sangram S.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-15 21:36:14

GCD jest rzeczywiście niższym poziomem niż NSOperationQueue, jego główną zaletą jest to, że jego implementacja jest bardzo lekka i koncentruje się na algorytmach bez blokady i wydajności.

NSOperationQueue zapewnia udogodnienia, które nie są dostępne w GCD, ale pochodzą z nietrywialnych kosztów, implementacja NSOperationQueue jest złożona i ciężka, wymaga wielu blokowania i używa GCD wewnętrznie tylko w bardzo minimalny sposób.

Jeśli potrzebujesz udogodnień oferowanych przez NSOperationQueue za wszelką cenę go używać, ale jeśli GCD jest wystarczająca dla Twoich potrzeb, polecam go używać bezpośrednio dla lepszej wydajności, znacznie niższe koszty CPU i energii oraz większą elastyczność.

 33
Author: das,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-03 16:13:51

Innym powodem preferowania Nsoperacji nad GCD jest mechanizm anulowania Nsoperacji. Na przykład, aplikacja taka jak 500px, która pokazuje dziesiątki zdjęć, użyj NSOperation możemy anulować żądania niewidocznych komórek obrazu podczas przewijania widoku tabeli lub widoku kolekcji, może to znacznie poprawić wydajność aplikacji i zmniejszyć ślad pamięci. GCD nie może tego łatwo obsługiwać.

Również z NSOperation, KVO może być możliwe.

Tutaj jest artykuł z eschatonu, który warto czytam.

 33
Author: evanchin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-19 20:21:45

Zarówno NSQueueOperations, jak i GCD umożliwiają wykonywanie ciężkich zadań obliczeniowych w tle na oddzielnych wątkach, uwalniając główny bieżnik aplikacji UI.

Dobrze, na podstawie poprzedniego postu widzimy NSOperations ma addDependency tak, że można kolejkować swoje operacje jeden po drugim sekwencyjnie.

Ale czytałem też o kolejkach szeregowych GCD, które możesz utworzyć uruchamiając swoje operacje w kolejce używając dispatch_queue_create. Pozwoli to uruchomić zestaw operacji jeden po drugim w sekwencyjny sposób.

Nsqueueoperation Advantages over GCD:

  1. Pozwala na dodanie zależności i pozwala na usunięcie zależności, więc dla jednej transakcji można uruchomić sekwencyjnie za pomocą zależności, A dla innych transakcji uruchomić jednocześnie, podczas gdy GCD nie pozwala biegać w ten sposób.

  2. Łatwo jest anulować operację, jeśli jest w kolejce, można ją zatrzymać, jeśli jest uruchomiona.

  3. Możesz określić maksymalną liczbę jednoczesnych szef.

  4. Możesz zawiesić operacje, które są w kolejce

  5. Możesz sprawdzić, ile oczekujących operacji znajduje się w kolejce.

 23
Author: Shashi3456643,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-31 01:43:44

GCD jest bardzo łatwy w użyciu-jeśli chcesz zrobić coś w tle, wystarczy, że napiszesz kod i wyślesz go do kolejki w tle. Robienie tego samego z Nsoperacja to dużo dodatkowej pracy.

Zaletą NSOperation jest to, że (a) masz prawdziwy obiekt, do którego możesz wysyłać wiadomości, oraz (b) że możesz anulować nsoperation. To nie jest trywialne. Musisz podklasować NSOperation, musisz poprawnie napisać kod, aby anulowanie i prawidłowe zakończenie zadania oba działają poprawnie. Więc dla prostych rzeczy używasz GCD, a dla bardziej skomplikowanych rzeczy tworzysz podklasę NSOperation. (Istnieją podklasy NSInvocationOperation i NSBlockOperation, ale wszystko, co robią, jest łatwiejsze z GCD, więc nie ma powodu, aby z nich korzystać).

 5
Author: gnasher729,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-06 00:41:19

Cóż, NSOperations to po prostu API zbudowane na bazie Grand Central Dispatch. Więc kiedy używasz NSOperations, naprawdę nadal używasz Grand Central Dispatch. Chodzi o to, że NSOperations daje kilka fantazyjnych funkcji, które mogą ci się spodobać. Możesz uzależnić niektóre operacje od innych operacji, zmienić kolejność kolejek po zsumowaniu elementów i innych podobnych rzeczy. W rzeczywistości ImageGrabber korzysta już z nsoperations i kolejek operacji! ASIHTTPRequest używa ich pod maską, a Ty można skonfigurować kolejkę operacji, której używa do różnych zachowań, jeśli chcesz. Więc czego powinieneś użyć? Niezależnie od tego, co ma sens dla Twojej aplikacji. W przypadku tej aplikacji jest to dość proste, więc po prostu użyliśmy bezpośrednio Grand Central Dispatch, nie ma potrzeby korzystania z fantazyjnych funkcji NSOperation. Ale jeśli potrzebujesz ich do swojej aplikacji, możesz z niej korzystać!

 3
Author: Ankul Gaur,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-13 11:40:15