2016-06-28 20 views
0

Ich habe Situation, wo ich meine Array-Objekte mit EnumerateObjectsUsingBlock Iterieren, und ich muss auf eine Fertigstellung in der Iteration warten, dann sollte es weiteren Code ausführen, wie kann ich dies erreichen, oder wenn eine Alternative ich sollte Verwendung, unten ist mein CodeenumerateObjectsUsingBlock und Abschluss zusammen

[arrPendingQueue enumerateObjectsUsingBlock:^(PendingQueues *obj, NSUInteger idx, BOOL *stop) { 

     //Fetch static google map based on coordinates 
     [self generateMapImage:obj.postObj completion:^(UIImage *image) { 
      NSString *path = [NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES).firstObject stringByAppendingPathComponent:@"camera"]; 

      NSString *resultPath = [path stringByAppendingPathComponent:[NSString stringWithFormat:@"map_%f.jpg",[[Constants getSystemDateInLocalTimeZone] timeIntervalSince1970]]]; 

      [[NSFileManager defaultManager] createFileAtPath:resultPath contents:UIImageJPEGRepresentation(image, 1.0) attributes:nil]; 

      postObj.imagepath = [@"camera" stringByAppendingPathComponent:[resultPath lastPathComponent]]; 

      [DataManager saveObject:postObj];            
     }]; 

     //After the completion I want to upload the data here to server 

}); 

Grundsätzlich versuche ich, statisch google map zum Download von in Funktion koordiniere generateMapImage und ich mag die Schleife bis zur Fertigstellung warten, genannt ..

Dafür habe ich versucht, zu verwenden, dispatch_semaphore_create wie

[arrPendingQueue enumerateObjectsUsingBlock:^(PendingQueues *obj, NSUInteger idx, BOOL *stop) { 
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); 

    [self generateMapImage:obj.postObj completion:^(UIImage *image) { 

     dispatch_semaphore_signal(semaphore);          
    }]; 

    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); 

}); 

Aber es funktioniert nicht, es wartet nicht, und führt den Code vor der Fertigstellung abgeschlossen.

Wie zu lösen, bitte helfen Sie.

Danke.

+0

Verwenden Sie die benutzerdefinierte Unterklasse 'NSOperation' –

+0

Möchten Sie in jedem Schritt auf den Abschluss einer einzelnen Operation warten oder möchten Sie auf den Abschluss aller Operationen warten? –

+0

@ AminNegm-Awad Abschluss einer einzigen Operation in jedem Schritt. – iphonic

Antwort

1

Um die Ausführung einer Reihe von A-Blöcke anstehen, können Sie einfach den neuen Block in der Fertigstellung Handler des alten Blocks beginnen:

NSEnumerator *objectEnum = [arrPendingQueue objectEnumerator]; 
__block void (^handler)(); 
handler = ^(UIImage *image) 
{ 
    // Handle image 
    object = [objectEnum nextObject]; 
    if(object == nil) 
    { 
    // completion of all operations 
    } 
    else 
    { 
    // Start next operation 
    [self generateMapImage:object.postObj completion:handler]; 
    }          
}; 
[self generateMapImage:obj.postObj completion:handler]; 
} 

Eine klassische und elegante Art und Weise ein Y-combinator zu verwenden wäre . Aber es ist nicht notwendig. Bedenken Sie jedoch, dass lokale Bereichsvariablen bereinigt werden, wenn sie ihren Gültigkeitsbereich verlieren. handler wird nicht beibehalten. Vielleicht musst du es in einen Ivar stecken.

Allerdings sehe ich -generateMapImage:completion wird von Ihnen geschrieben. Ich kann den Inhalt nicht sehen, aber wenn Sie dort einen asynchronen Anruf ausführen und die für den Anruf verwendete Warteschlange festlegen können, müssen Sie ihn einfach auf eine serielle Warteschlange einstellen. In diesem Fall werden Ihre Anfragen automatisch seriell ausgeführt.