2016-06-28 21 views
0

enumerateObjectsUsingBlockを使用して配列オブジェクトを反復処理している状況があります。反復処理の完了を待つ必要があり、コードをさらに実行する必要があります。以下の使用は、私のコードは基本的に、私は機能generateMapImageの座標から静的のGoogleマップをダウンロードしようとしていると私はループと呼ばれる完了まで待ちたい...そのためにenumerateObjectsUsingBlockと補完を併用する

私が使用しようとした

[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 

}); 

ですdispatch_semaphore_createのように

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

}); 

しかし、それはうまくいきません、それは完了しないうちに、コードを実行し、完了しません。

解決方法、お手伝いください。

ありがとうございました。一連のブロックの実行をキューに

+0

カスタム 'NSOperation'サブクラスを使用 –

+0

各ステップで1回の操作の完了を待つか、すべての操作の完了を待つかしますか? –

+0

@ AminNegm-Awad各ステップでの1回の操作の完了。 – iphonic

答えて

1

、あなたは単に古いブロックの完了ハンドラ内で新しいブロックを開始することができます:

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

より古典やエレガントな方法はY-combinatorを使用することです。しかし、それは必要ではありません。スコープを失うとローカルスコープ変数がクリーンアップされることに留意してください。 handlerは保持されません。だから多分あなたはそれを象牙に入れる必要があります。

ただし、-generateMapImage:completionはあなたの手紙です。私はコンテンツを見ることができませんが、そこで非同期呼び出しを行い、呼び出しに使用されるキューを設定できる場合は、単純にシリアルキューに設定してください。そのような場合、リクエストは自動的にシリアルで実行されます。