2016-06-28 2 views
0

Je suis en situation d'itération de mes objets tableau en utilisant enumerateObjectsUsingBlock, et j'ai besoin d'attendre une fin dans l'itération alors il faut exécuter du code supplémentaire, comment puis-je y arriver, ou si je devais alterner l'utilisation, ci-dessous est mon codeenumerateObjectsUsingBlock et complétion ensemble

[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 

}); 

Fondamentalement, je suis en train de télécharger google map statique de coordonnées dans la fonction generateMapImage et je veux la boucle d'attendre jusqu'à l'achèvement appelé ..

pour que j'ai essayé d'utiliser dispatch_semaphore_create comme

[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); 

}); 

Mais cela ne fonctionne pas, il n'attend pas, et exécute le code avant la fin terminée.

Comment procéder pour résoudre, s'il vous plaît aide.

Merci.

+0

Utilisation de la sous-classe personnalisée 'NSOperation' –

+0

Souhaitez-vous attendre l'achèvement d'une seule opération à chaque étape ou souhaitez-vous attendre la fin de toutes les opérations? –

+0

@ AminNegm-Awad Achèvement d'une seule opération à chaque étape. – iphonic

Répondre

1

faire la queue exécution d'une série d'un des blocs, vous pouvez simplement lancer le nouveau bloc dans le gestionnaire d'achèvement de l'ancien bloc:

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]; 
} 

Une façon plus classique ou élégante serait d'utiliser un Y-combinator . Mais ce n'est pas nécessaire. Gardez simplement à l'esprit que les variables d'étendue locales sont nettoyées lorsqu'elles perdent leur portée. handler n'est pas conservé. Alors peut-être que vous devez le mettre dans un ivar.

Cependant, je vois -generateMapImage:completion est écrit par vous. Je ne vois pas le contenu, mais si vous effectuez un appel asynchrone et que vous pouvez définir la file d'attente utilisée pour l'appel, définissez-le simplement sur une file d'attente série. Dans ce cas, vos demandes seront exécutées en série automatiquement.