Ich lerne etwas über gleichzeitiges Programmieren für iOS. Bisher habe ich über NSOperation
/NSOperationQueue
und gelesen GCD
. Was sind die Gründe für die Verwendung von NSOperationQueue
over GCD
und umgekehrt?
Klingt nach beidem GCD
und NSOperationQueue
abstrahiert die explizite Erstellung NSThreads
vom Benutzer. Die Beziehung zwischen den beiden Ansätzen ist mir jedoch nicht klar, so dass jedes Feedback geschätzt wird!
ios
concurrency
grand-central-dispatch
nsoperation
nsoperationqueue
Sonntag Montag
quelle
quelle
Antworten:
GCD
ist eine C-basierte API auf niedriger Ebene, die die sehr einfache Verwendung eines aufgabenbasierten Parallelitätsmodells ermöglicht.NSOperation
undNSOperationQueue
sind Objective-C-Klassen, die etwas Ähnliches tun.NSOperation
wurde zuerst eingeführt, aber ab 10.5 und iOS 2 ,NSOperationQueue
und Freunde werden intern mit implementiertGCD
.Im Allgemeinen sollten Sie die höchste Abstraktionsebene verwenden, die Ihren Anforderungen entspricht. Dies bedeutet, dass Sie normalerweise
NSOperationQueue
anstelle von verwenden solltenGCD
, es sei denn, Sie müssen etwas tun,NSOperationQueue
das nicht unterstützt wird.Beachten Sie, dass dies
NSOperationQueue
keine "heruntergekommene" Version von GCD ist. In der Tat gibt es viele Dinge, die Sie sehr einfach tun könnenNSOperationQueue
, die viel Arbeit mit pur erfordernGCD
. (Beispiele: Warteschlangen mit eingeschränkter Bandbreite, die jeweils nur N Operationen ausführen; Abhängigkeiten zwischen Operationen herstellen. Beides sehr einfachNSOperation
, sehr schwierigGCD
.) Apple hat die harte Arbeit geleistet, GCD zu nutzen, um eine sehr schöne objektfreundliche API mit zu erstellenNSOperation
. Nutzen Sie ihre Arbeit, es sei denn, Sie haben einen Grund, dies nicht zu tun.Vorsichtsmaßnahme : Wenn Sie jedoch wirklich nur einen Block senden müssen und keine der zusätzlichen Funktionen benötigen, die
NSOperationQueue
bereitgestellt werden, ist die Verwendung von GCD nichts Falsches. Stellen Sie nur sicher, dass es das richtige Werkzeug für den Job ist.quelle
In Übereinstimmung mit meiner Antwort auf eine verwandte Frage werde ich BJ nicht zustimmen und vorschlagen, dass Sie sich zuerst GCD über NSOperation / NSOperationQueue ansehen, es sei denn, letzteres bietet etwas, das Sie benötigen, das GCD nicht benötigt.
Vor GCD habe ich in meinen Anwendungen viele NSOperations / NSOperationQueues zum Verwalten der Parallelität verwendet. Seit ich GCD regelmäßig verwende, 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 entsteht bei der Verwendung von NSOperations und NSOperationQueues ein nicht trivialer Overhead. Dies sind Kakaoobjekte, die zugewiesen und freigegeben werden müssen. In einer von mir geschriebenen iOS-Anwendung, die eine 3D-Szene mit 60 FPS rendert, habe ich NSOperations verwendet, um jeden gerenderten Frame zu kapseln. Als ich dies profilierte, machte das Erstellen und Herunterfahren dieser NSOperations einen erheblichen Teil der CPU-Zyklen in der laufenden Anwendung aus und verlangsamte die Dinge. Ich habe diese durch einfache Blöcke und eine serielle GCD-Warteschlange ersetzt, und dieser Overhead verschwand, was zu einer deutlich besseren Renderleistung führte. Dies war nicht der einzige Ort, an dem ich durch die Verwendung von NSOperations einen 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 zu packen und ihn in einer seriellen oder gleichzeitigen Warteschlange zu versenden, wo das Erstellen einer benutzerdefinierten NSOperation oder NSInvocationOperation viel mehr unterstützenden Code erfordert. 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 im Einklang mit der zugehörigen Verarbeitung in Ihrer Anwendung führt meiner Meinung nach zu einer besseren Codeorganisation als separate Methoden oder benutzerdefinierte NSOperations, die diese Aufgaben kapseln.
NSOperations und NSOperationQueues haben immer noch sehr gute Verwendungsmöglichkeiten. GCD hat kein wirkliches Konzept von Abhängigkeiten, bei denen NSOperationQueues ziemlich komplexe Abhängigkeitsgraphen erstellen kann. In einigen Fällen verwende ich dafür NSOperationQueues.
Insgesamt plädiere ich zwar für die Verwendung der höchsten Abstraktionsebene, die die Aufgabe erfüllt, aber dies ist ein Fall, in dem ich mich für die untergeordnete API von GCD ausspreche. Unter den iOS- und Mac-Entwicklern, mit denen ich darüber gesprochen habe, wählt die überwiegende Mehrheit GCD anstelle von NSOperations, es sei denn, sie zielen auf Betriebssystemversionen ab, die dies nicht unterstützen (jene vor iOS 4.0 und Snow Leopard).
quelle
GCD
ist eine C-basierte API auf niedriger Ebene.NSOperation
undNSOperationQueue
sind Objective-C-Klassen.NSOperationQueue
ist objektiv C Wrapper vorbeiGCD
. Wenn Sie NSOperation verwenden, verwenden Sie implizit Grand Central Dispatch.GCD-Vorteil gegenüber NSOperation:
i. Implementierung
Für die
GCD
Implementierung ist sehr leicht,NSOperationQueue
komplex und schwerVorteile von NSOperation gegenüber GCD:
ich. Control On Operation können
Sie anhalten, abbrechen, fortsetzen
NSOperation
ii. Abhängigkeiten, mit denen
Sie eine Abhängigkeit zwischen zwei
NSOperations
Vorgängen einrichten können, werden erst gestartet, wenn alle Abhängigkeiten true für "beendet" zurückgegeben haben.
iii. Der Betriebsstatus
kann den Status eines Vorgangs oder einer Betriebswarteschlange überwachen. bereit, ausführend oder fertig
iv.
Maximale Anzahl von Vorgängen Sie können die maximale Anzahl von Vorgängen in der Warteschlange angeben, die gleichzeitig ausgeführt werden können
Wann
GCD
oderNSOperation
wann Sie mehr Kontrolle über die Verwendung der Warteschlange (alle oben genannten)
NSOperation
und für einfache Fälle, in denen Sie weniger Overhead wünschen (Sie möchten nur etwas Arbeit "im Hintergrund" mit sehr wenig zusätzlicher Arbeit erledigen)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/
quelle
Ein weiterer Grund, NSOperation gegenüber GCD zu bevorzugen, ist der Aufhebungsmechanismus von NSOperation. Beispiel: Bei einer App wie 500px, die Dutzende von Fotos anzeigt, können Sie mithilfe von NSOperation Anforderungen von unsichtbaren Bildzellen abbrechen, wenn wir durch die Tabellen- oder Sammlungsansicht scrollen. Dies kann die App-Leistung erheblich verbessern und den Speicherbedarf verringern. GCD kann dies nicht einfach unterstützen.
Auch mit NSOperation kann KVO möglich sein.
Hier ist ein Artikel von Eschaton, der es wert ist, gelesen zu werden.
quelle
NSOperation
dafür, wieNSURLSessionTask.cancel
undNSURLSession.invalidateAndCancel
diese Funktionalität bereitstellen. Im AllgemeinenNSURLSession
stellt einen Teil der Funktionalität einesNSOperationQueue
, alsNSURLSessionTask
einen Teil der Funktionalität eines bietetNSOperation
GCD ist in der Tat niedriger als NSOperationQueue. Sein Hauptvorteil besteht darin, dass seine Implementierung sehr leicht ist und sich auf sperrfreie Algorithmen und Leistung konzentriert.
NSOperationQueue bietet Funktionen, die in GCD nicht verfügbar sind, die jedoch nicht trivial sind. Die Implementierung von NSOperationQueue ist komplex und schwer, erfordert viel Sperren und verwendet GCD intern nur in sehr geringem Umfang.
Wenn Sie die von NSOperationQueue bereitgestellten Funktionen benötigen, verwenden Sie sie auf jeden Fall. Wenn GCD jedoch für Ihre Anforderungen ausreicht, würde ich empfehlen, es direkt zu verwenden, um eine bessere Leistung, deutlich niedrigere CPU- und Stromkosten sowie mehr Flexibilität zu erzielen.
quelle
Sowohl NSQueueOperations als auch GCD ermöglichen die Ausführung einer umfangreichen Rechenaufgabe im Hintergrund in separaten Threads, indem der Hauptbereich der UI-Anwendung freigegeben wird.
Basierend auf dem vorherigen Beitrag sehen wir, dass NSOperations addDependency hat, so dass Sie Ihre Operation nacheinander in die Warteschlange stellen können.
Ich habe aber auch über serielle GCD-Warteschlangen gelesen, die Sie erstellen können, um Ihre Vorgänge in der Warteschlange mit dispatch_queue_create auszuführen. Auf diese Weise können Sie eine Reihe von Vorgängen nacheinander ausführen.
Vorteile von NSQueueOperation gegenüber GCD:
Es ermöglicht das Hinzufügen von Abhängigkeiten und das Entfernen von Abhängigkeiten, sodass Sie für eine Transaktion sequenziell mithilfe von Abhängigkeiten und für andere Transaktionen gleichzeitig ausgeführt werden können, während GCD die Ausführung auf diese Weise nicht zulässt.
Es ist einfach, einen Vorgang abzubrechen, wenn er sich in der Warteschlange befindet. Er kann gestoppt werden, wenn er ausgeführt wird.
Sie können die maximale Anzahl gleichzeitiger Vorgänge definieren.
Sie können den Vorgang in der Warteschlange anhalten
Sie können feststellen, wie viele ausstehende Vorgänge sich in der Warteschlange befinden.
quelle
GCD ist sehr einfach zu bedienen. Wenn Sie etwas im Hintergrund tun möchten, müssen Sie nur den Code schreiben und ihn in eine Hintergrundwarteschlange stellen. Dasselbe mit NSOperation zu tun, ist eine Menge zusätzlicher Arbeit.
Der Vorteil von NSOperation besteht darin, dass (a) Sie ein reales 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 in eine Unterklasse unterteilen. Sie müssen Ihren Code korrekt schreiben, damit das Abbrechen und das korrekte 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 Unterklassen NSInvocationOperation und NSBlockOperation, aber alles, was sie tun, ist mit GCD einfacher, sodass es keinen guten Grund gibt, sie zu verwenden.)
quelle
Nun, NSOperations sind einfach eine API, die auf Grand Central Dispatch basiert. 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 nach dem Versenden von Elementen neu anordnen und ähnliche Dinge. Tatsächlich verwendet ImageGrabber bereits NSOperations und Operationswarteschlangen! ASIHTTPRequest verwendet sie unter der Haube, und Sie können die verwendete Operationswarteschlange für ein anderes Verhalten konfigurieren, wenn Sie möchten. Also was solltest du verwenden? Was auch immer für Ihre App sinnvoll ist. 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!
quelle