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).