it-swarm.com.de

NSOperation gegen Grand Central Dispatch

Ich lerne etwas über gleichzeitiges Programmieren für iOS. Bisher habe ich über NSOperation/NSOperationQueue und GCD gelesen. Aus welchen Gründen wird NSOperationQueue anstelle von GCD verwendet und umgekehrt?

Klingt so, als ob sowohl GCD als auch NSOperationQueue die explizite Erstellung von NSThreads vom Benutzer abstrahieren. Allerdings ist mir die Beziehung zwischen den beiden Ansätzen nicht klar, sodass ich jedes Feedback zu schätzen weiß!

451
SundayMonday

GCD ist eine C-basierte API auf niedriger Ebene, die die sehr einfache Verwendung eines aufgabenbasierten Parallelitätsmodells ermöglicht. NSOperation und NSOperationQueue sind Objective-C-Klassen, die ähnliche Aktionen ausführen. NSOperation wurde zuerst eingeführt, aber seit 10.6 und iOS 4 werden NSOperationQueue und friends intern mit GCD implementiert.

Im Allgemeinen sollten Sie die höchste Abstraktionsebene verwenden, die Ihren Anforderungen entspricht. Dies bedeutet, dass Sie normalerweise NSOperationQueue anstelle von GCD verwenden sollten, es sei denn, Sie müssen etwas tun, das NSOperationQueue nicht unterstützt.

Beachten Sie, dass NSOperationQueue keine "heruntergekommene" Version von GCD ist. Tatsächlich gibt es viele Dinge, die Sie sehr einfach mit NSOperationQueue tun können und die viel Arbeit mit reinem GCD erfordern. (Beispiele: Warteschlangen mit eingeschränkter Bandbreite, in denen jeweils nur N Vorgänge ausgeführt werden; Festlegen von Abhängigkeiten zwischen Vorgängen. Beides ist mit NSOperation sehr einfach und mit GCD sehr schwierig.) Apple hat die harte Arbeit geleistet GCD zum Erstellen einer sehr netten objektfreundlichen API mit NSOperation. Nutzen Sie ihre Arbeit, es sei denn, Sie haben einen Grund, dies nicht zu tun.

Einschränkung: Wenn Sie dagegen wirklich nur einen Block absenden müssen und keine der zusätzlichen Funktionen benötigen, die NSOperationQueue bietet, ist die Verwendung von GCD kein Problem . Stellen Sie nur sicher, dass es das richtige Werkzeug für den Job ist.

509
BJ Homer

In Übereinstimmung mit meine Antwort auf eine verwandte Frage werde ich BJ widersprechen und vorschlagen, dass Sie sich zuerst GCD über NSOperation/NSOperationQueue ansehen, es sei denn, letzteres bietet etwas, das Sie brauchen, was GCD nicht benötigt.

Vor GCD habe ich viele NSOperations/NSOperationQueues in meinen Anwendungen zum Verwalten der Parallelität verwendet. Seit ich GCD regelmäßig benutze, habe ich NSOperations und NSOperationQueues fast vollständig durch Blöcke und Versandwarteschlangen ersetzt. Dies ist darauf zurückzuführen, wie ich beide Technologien in der Praxis eingesetzt habe und wie ich sie profiliert habe.

Erstens ist der Aufwand bei der Verwendung von NSOperations und NSOperationQueues nicht unerheblich. Dies sind Cocoa-Objekte, die zugewiesen und freigegeben werden müssen. In einer von mir geschriebenen iOS-Anwendung, die eine 3-D-Szene mit 60 FPS wiedergibt, verwendete ich NSOperations, um jeden gerenderten Frame zu kapseln. Als ich dieses Profil erstellte, machte das Erstellen und Herunterfahren dieser NSOperations einen erheblichen Teil der CPU-Zyklen in der ausgeführten Anwendung aus und verlangsamte die Ausführung. Ich habe diese durch einfache Blöcke und eine serielle GCD-Warteschlange ersetzt, und dieser Overhead verschwand, was zu einer spürbar besseren Renderleistung führte. Dies war nicht der einzige Ort, an dem ich durch die Verwendung von NSOperations Overhead bemerkte, und ich habe dies sowohl auf Mac als auch auf iOS gesehen.

Zweitens hat blockbasierter Versandcode eine Eleganz, die bei Verwendung von NSOperations nur schwer zu erreichen ist. Es ist unglaublich praktisch, ein paar Codezeilen in einen Block einzubinden und für die Ausführung in einer seriellen oder gleichzeitigen Warteschlange zu verteilen, wobei für die Erstellung einer benutzerdefinierten NSOperation oder NSInvocationOperation viel mehr unterstützender Code erforderlich ist. Ich weiß, dass Sie eine NSBlockOperation verwenden können, aber Sie könnten dann genauso gut etwas an GCD senden. Das Umschließen dieses Codes in Blöcke in Übereinstimmung mit der zugehörigen Verarbeitung in Ihrer Anwendung führt meiner Meinung nach zu einer besseren Codeorganisation als separate Methoden oder benutzerdefinierte NSOperations, in denen diese Aufgaben zusammengefasst sind.

NSOperations und NSOperationQueues haben immer noch sehr gute Verwendungen. GCD kennt kein wirkliches Abhängigkeitskonzept, mit dem NSOperationQueues ziemlich komplexe Abhängigkeitsgraphen erstellen kann. In einigen Fällen verwende ich dafür NSOperationQueues.

Während ich normalerweise die Verwendung der höchsten Abstraktionsebene befürworte, die die Aufgabe erfüllt, ist dies ein Fall, in dem ich mich für die niedrigere API-Ebene von GCD aussetze. Unter den iOS- und Mac-Entwicklern, mit denen ich darüber gesprochen habe, entscheidet sich die überwiegende Mehrheit für die Verwendung von GCD gegenüber NSOperations, es sei denn, sie zielen auf Betriebssystemversionen ab, die dies nicht unterstützen (vor iOS 4.0 und Snow Leopard).

364
Brad Larson

GCD ist eine C-basierte API auf niedriger Ebene.
NSOperation und NSOperationQueue sind Objective-C-Klassen.
NSOperationQueue ist Objective C-Wrapper über GCD. Wenn Sie NSOperation verwenden, verwenden Sie implizit Grand Central Dispatch.

GCD-Vorteil gegenüber NSOperation:
i. Implementierung
Für GCD ist die Implementierung sehr leicht
NSOperationQueue ist komplex und schwer

Vorteile von NSOperation gegenüber GCD:

i. Bedienung ein
Sie können pausieren, abbrechen, ein NSOperation fortsetzen

ii. Abhängigkeiten
Sie können eine Abhängigkeit zwischen zwei NSOperations einrichten.
Die Operation wird erst gestartet, wenn alle Abhängigkeiten für "erledigt" auf "wahr" gesetzt sind.

iii. Betriebszustand
kann den Status einer Operation oder Operationswarteschlange überwachen. bereit, ausgeführt oder beendet

iv. Maximale Anzahl der Operationen
Sie können die maximale Anzahl von Vorgängen in der Warteschlange angeben, die gleichzeitig ausgeführt werden können

Zeitpunkt für GCD oder NSOperation
Wenn Sie mehr Kontrolle über die Warteschlange haben möchten (alle oben genannten), verwenden Sie NSOperation und für einfache Fälle, in denen Sie weniger Overhead benötigen (Sie möchten nur einige Arbeiten "im Hintergrund" mit sehr wenig zusätzlichem Aufwand ausführen Arbeit) benutze GCD

ref:
https://cocoacasts.com/choosing-between-nsoperation-and-grand-central-dispatch/http://iosinfopot.blogspot.in/2015/ 08/nsthread-vs-gcd-vs-nsoperationqueue.htmlhttp://nshipster.com/nsoperation/

89

Ein weiterer Grund, NSOperation gegenüber GCD vorzuziehen, ist der Kündigungsmechanismus von NSOperation. Zum Beispiel kann eine App wie 500px, die Dutzende von Fotos zeigt, mithilfe von NSOperation Anfragen nach unsichtbaren Bildzellen stornieren, wenn wir in der Tabellen- oder Sammlungsansicht scrollen. Dies kann die Leistung der App erheblich verbessern und den Speicherbedarf verringern. GCD kann dies nicht einfach unterstützen.

Auch mit NSOperation kann KVO möglich sein.

hier ist ein lesenswerter Artikel von Eschaton.

34
evanchin

GCD ist in der Tat niedriger als NSOperationQueue. Sein Hauptvorteil ist, dass seine Implementierung sehr leicht ist und sich auf Algorithmen und Leistung ohne Sperren konzentriert.

NSOperationQueue bietet zwar Funktionen, die in GCD nicht verfügbar sind, diese sind jedoch nicht trivial. Die Implementierung von NSOperationQueue ist komplex und aufwändig, erfordert viel Sperren und verwendet GCD intern nur in sehr geringem Umfang.

Wenn Sie die von NSOperationQueue bereitgestellten Funktionen auf jeden Fall benötigen, aber wenn GCD für Ihre Anforderungen ausreicht, würde ich empfehlen, es direkt zu verwenden, um die Leistung zu verbessern, die CPU- und Stromkosten deutlich zu senken und die Flexibilität zu erhöhen.

33
das

Sowohl NSQueueOperations als auch GCD ermöglichen die Ausführung umfangreicher Rechenaufgaben im Hintergrund auf separaten Threads, indem das Hauptprofil der Benutzeroberflächenanwendung freigegeben wird.

Nun, basierend auf dem vorherigen Beitrag sehen wir, dass NSOperations addDependency hat, so dass Sie Ihre Operation nacheinander sequenziell in die Warteschlange stellen können.

Ich habe aber auch etwas über serielle GCD-Warteschlangen gelesen, die Sie mit dispatch_queue_create erstellen können, um Ihre Vorgänge in der Warteschlange auszuführen. Auf diese Weise können mehrere Vorgänge nacheinander ausgeführt werden.

Vorteile von NSQueueOperation gegenüber GCD:

  1. Es ermöglicht das Hinzufügen von Abhängigkeiten und das Entfernen von Abhängigkeiten, sodass Sie für eine Transaktion mithilfe von Abhängigkeiten sequentiell und für andere Transaktionen gleichzeitig ausführen können, während GCD dies nicht zulässt.

  2. Es ist einfach, eine Operation abzubrechen, wenn sie sich in der Warteschlange befindet. Sie kann angehalten werden, wenn sie ausgeführt wird.

  3. Sie können die maximale Anzahl gleichzeitiger Vorgänge festlegen.

  4. Sie können den Vorgang anhalten, der sich in der Warteschlange befindet

  5. Sie können feststellen, wie viele ausstehende Vorgänge sich in der Warteschlange befinden.

23
Shashi3456643

GCD ist sehr einfach zu bedienen. Wenn Sie etwas im Hintergrund tun möchten, müssen Sie nur den Code schreiben und in eine Hintergrundwarteschlange stellen. Dasselbe mit NSOperation zu tun, ist eine Menge zusätzlicher Arbeit.

Der Vorteil von NSOperation ist, dass (a) Sie ein echtes Objekt haben, an das Sie Nachrichten senden können, und (b) dass Sie eine NSOperation abbrechen können. Das ist nicht trivial. Sie müssen NSOperation als Unterklasse definieren und Ihren Code korrekt schreiben, damit sowohl das Abbrechen als auch das ordnungsgemäße Beenden einer Aufgabe ordnungsgemäß funktionieren. Für einfache Dinge verwenden Sie GCD, und für kompliziertere Dinge erstellen Sie eine Unterklasse von NSOperation. (Es gibt die Unterklassen NSInvocationOperation und NSBlockOperation, aber alles, was sie tun, ist mit GCD einfacher. Es gibt also keinen guten Grund, sie zu verwenden.).

5
gnasher729

Nun, NSOperations ist einfach eine API, die auf Grand Central Dispatch aufbaut. Wenn Sie also NSOperations verwenden, verwenden Sie immer noch Grand Central Dispatch. Es ist nur so, dass NSOperations Ihnen einige ausgefallene Funktionen bietet, die Ihnen gefallen könnten. Sie können einige Vorgänge von anderen Vorgängen abhängig machen, Warteschlangen neu anordnen, nachdem Sie Elemente ausgelesen haben, und ähnliche Dinge. Tatsächlich verwendet ImageGrabber bereits NSOperations und Operationswarteschlangen! ASIHTTPRequest verwendet sie unter der Haube und Sie können die Operationswarteschlange konfigurieren, die für ein anderes Verhalten verwendet wird, wenn Sie möchten. Also welche solltest du verwenden? Was auch immer für Ihre App Sinn macht. Für diese App ist es ziemlich einfach, also haben wir Grand Central Dispatch direkt verwendet, ohne die ausgefallenen Funktionen von NSOperation zu benötigen. Aber wenn Sie sie für Ihre App benötigen, können Sie sie gerne verwenden!

3
Ankul Gaur