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:

  1. ein Objekt hat eine Methode, die eine HTTP-Anforderung von dem es
    wird einigen Daten, einschließlich einer URL zu einem Bild
  2. sobald die Daten eintreffen, werden die textuellen Daten zum Auffüllen eines
    CoreData-Modell
  3. 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.
  4. 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.
  5. 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

Schreibe einen Kommentar