Wie soll ich GCD dispatch_barrier_async in iOS (scheint ausgeführt werden, bevor und nicht nach anderen Blöcke)
Ich versuche, zu synchronisieren, die folgenden code in iOS5:
- ein Objekt hat eine Methode, die eine HTTP-Anforderung von dem es
wird einigen Daten, einschließlich einer URL zu einem Bild - sobald die Daten eintreffen, werden die textuellen Daten zum Auffüllen eines
CoreData-Modell - gleichzeitig einen zweiten thread ausgelöst async downloaden
das Bild; in diesem thread wird das signal über KVO zu einem viewController, wenn
das Bild ist bereits im Cache und in die CoreData-Modell. - seit den image-download wird eine Weile dauern, setzen wir uns umgehend zurück
das CoreData-Objekt, das alle Attribute aber für das Bild
der Aufrufer. - Auch, wenn der zweite thread fertig ist das herunterladen, die CoreData-Modell
können gespeichert werden.
Dies ist der (vereinfachte) code:
- (void)insideSomeMethod
{
[SomeHTTPRequest withCompletionHandler:
^(id retrievedData)
{
if(!retrievedData)
{
handler(nil);
}
//Populate CoreData model with retrieved Data...
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
NSURL* userImageURL = [NSURL URLWithString:[retrievedData valueForKey:@"imageURL"]];
aCoreDataNSManagedObject.profileImage = [NSData dataWithContentsOfURL:userImageURL];
});
handler(aCoreDataNSManagedObject);
[self shouldCommitChangesToModel];
}];
}
- (void)shouldCommitChangesToModel
{
dispatch_barrier_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
NSError *error = nil;
if(![managedObjectContext save:&error])
{
// Handle error
}
});
}
Aber was passiert ist, dass die Barriere-basierten speichern-block wird immer ausgeführt, bevor der Bild-laden-block. Das ist,
dispatch_barrier_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
NSError *error = nil;
if(![managedObjectContext save:&error])
{
// Handle error
}
});
Führt vor:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
NSURL* userImageURL = [NSURL URLWithString:[retrievedData valueForKey:@"imageURL"]];
aCoreDataNSManagedObject.profileImage = [NSData dataWithContentsOfURL:userImageURL];
});
Also offensichtlich bin ich nicht wirklich Versendung der Bild-laden-block vor der Barriere, oder die Barriere würde warten, bis die Bild-laden-block durchgeführt, bevor die Ausführung (das war meine Absicht).
Was mache ich falsch? wie kann ich sicherstellen, dass der Bild-laden-block wird in die Warteschlange eingereiht, bevor die Barriere zu sperren?
InformationsquelleAutor der Frage SaldaVonSchwartz | 2012-05-30
Du musst angemeldet sein, um einen Kommentar abzugeben.
Auf den ersten Blick das Problem kann sein, dass Sie die Versendung der barrier block auf einer globalen gleichzeitigen Warteschlange. Sie können nur verwenden Sie Barriere-Blöcke auf einer eigenen gleichzeitigen Warteschlange. Pro der GCD docs auf dispatch_barrier_async, wenn Sie Versand ein block zu einer globalen Warteschlange, es verhält sich wie eine normale dispatch_async nennen.
Mike Ash hat einen guten blog-post auf GCD Barriere Blöcke: http://www.mikeash.com/pyblog/friday-qa-2011-10-14-whats-new-in-gcd.html
Glück
T
InformationsquelleAutor der Antwort timthetoolman
Müssen Sie erstellen Ihre eigenen queue und nicht die Absendung an die global-Warteschlangen, gemäß der ADC-Docs
vom https://developer.apple.com/library/ios/documentation/Performance/Reference/GCD_libdispatch_Ref/Reference/reference.html#//apple_ref/c/func/dispatch_barrier_async .
Können Sie erstellen, die Tonnen von Ihrem eigenen GCD Warteschlangen einfach nur gut. gcd-Warteschlangen sind sehr klein und Sie können Tonnen von Ihnen, ohne Frage. Sie brauchen nur, Sie zu befreien, wenn Sie fertig sind mit Ihnen.
InformationsquelleAutor der Antwort Colin Wheeler
Für das, was Sie zu sein scheinen, zu lösen versucht,
dispatch_barrier_async
vielleicht nicht die beste Lösung.Haben Sie einen Blick auf die Die Migration Weg Von Threads Abschnitt der Concurrency Programming Guide. Nur mit
dispatch_sync
auf eine eigene serielle Warteschlange lösen Ihr problem Synchronisation.Alternativ können Sie die NSOperation und NSOperationQueue. Im Gegensatz zu GCD, NSOperation ermöglicht Ihnen die einfache Verwaltung Abhängigkeiten (kann man es mit GCD, aber es kann schnell hässlich).
InformationsquelleAutor der Antwort quellish
Ich bin ein wenig spät zur party, aber vielleicht beim nächsten mal, Sie könnten versuchen, mit
dispatch_group
s zu Ihrem Vorteil. http://www.raywenderlich.com/63338/grand-central-dispatch-in-depth-part-2InformationsquelleAutor der Antwort Stephen Paul