2013-02-06 8 views
7

Im Wesentlichen habe ich eine Reihe von Daten in einem NSDictionary, aber aus Bequemlichkeit richte ich einige NSArray s mit den Daten sortiert und gefiltert auf ein paar verschiedene Arten. Die Daten werden über verschiedene Threads (Blöcke) eingehen, und ich möchte sicherstellen, dass immer nur ein Block meinen Datenspeicher ändert.@synchronisierter Block versus GCD dispatch_async()

Ich machte mir heute Nachmittag die Mühe, eine Versandwarteschlange einzurichten und stolperte dann zufällig auf einen Post über @synchronized, der es so aussehen ließ, als würde ich genau das tun, was ich machen wollte.

Also, was ich jetzt habe, ist ...

// a property on my object 
@property (assign) dispatch_queue_t matchSortingQueue; 

// in my object init 
_sortingQueue = dispatch_queue_create("com.asdf.matchSortingQueue", NULL); 

// then later... 
- (void)sortArrayIntoLocalStore:(NSArray*)matches 
{ 
    dispatch_async(_sortingQueue, ^{ 
     // do stuff... 
    }); 
} 

Und meine Frage ist, kann ich nur all dies mit folgendem ersetzen?

- (void)sortArrayIntoLocalStore:(NSArray*)matches 
{ 
    @synchronized (self) { 
     // do stuff... 
    }; 
} 

... Und was ist der Unterschied zwischen den beiden? Was sollte ich beachten?

+0

'@ synchronized' ist wirklich langsam. Ich kann die Messwerte, die ich gerade suche, nicht finden, aber überprüfe auch https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Multithreading/ThreadSafety/ThreadSafety.html. – Richard

+0

Wenn Ihre Daten über dieselbe Dispatch-Warteschlange (gleicher Thread) eingehen, stoßen sie nicht zusammen. Wenn Sie verschiedene Warteschlangen (verschiedene Threads) verwenden, wäre eine Synchronisierung notwendig. – Jeremy

+0

Es gefunden (via http://stackoverflow.com/q/10094361/480850): http://perpendiculo.us/?p=133 – Richard

Antwort

5

Obwohl der funktionale Unterschied für Sie nicht so wichtig ist, ist es das, was Sie erwarten würden: Wenn Sie @synchronize dann ist der Thread, den Sie sind blockiert, bis es exklusive Ausführung erhalten kann. Wenn Sie asynchron in eine serielle Dispatch-Warteschlange senden, kann der aufrufende Thread mit anderen Dingen weitermachen und was auch immer Sie gerade tun, wird immer in der gleichen, bekannten Warteschlange auftreten.

Sie sind also gleichbedeutend, um sicherzustellen, dass eine dritte Ressource aus nur einer Warteschlange gleichzeitig verwendet wird.

Dispatching könnte eine bessere Idee sein, wenn Sie beispielsweise eine Ressource haben, auf die die Benutzerschnittstelle von der Hauptwarteschlange aus zugreift und die Sie mutieren wollten. Dann braucht Ihr Benutzerschnittstellenkode nicht explizit auf @synchronize, und versteckt die Komplexität Ihres Threading-Schemas innerhalb des Objekts ganz natürlich. Dispatching ist auch eine bessere Idee, wenn Sie einen zentralen Akteur haben, der mehrere dieser Änderungen an anderen Akteuren auslösen kann; Dadurch können sie gleichzeitig arbeiten.

Synchronisieren ist kompakter und viel einfacher zu debuggen. Wenn das, was du tust, zwei oder drei Zeilen umfasst und du es sowieso synchron versenden musst, dann ist es nicht so, als ob du dich um die Erstellung einer Warteschlange kümmerst - besonders, wenn du die impliziten Kosten des Erstellens bedenkst ein Block und verschiebe es auf den Haufen.

+0

Danke für die ausführliche Antwort.Es klingt, als ob die asynchrone Warteschlange das ist, was ich wollte. – livingtech

4

Im zweiten Fall würden Sie den aufrufenden Thread blockieren, bis "Do Stuff" getan wurde. Mit Warteschlangen und dispatch_async blockieren Sie den aufrufenden Thread nicht. Dies ist besonders wichtig, wenn Sie sortArrayIntoLocalStore über den UI-Thread aufrufen.

Verwandte Themen