6

同期順に実行したい 4 つのメソッドを呼び出しています。最初の 2 つのメソッドは同期、最後の 2 つのメソッドは非同期 (URL からのデータ取得) です。

擬似コード:

- (void)syncData {

    // Show activity indicator
    [object sync]; // Synchronous method
    [object2 sync]; // Synchronous method
    BOOL object3Synced = [object3 sync]; // Async method
    BOOL object4Synced = [object4 sync]; // Async method
    // Wait for object3 and object4 has finished and then hide activity indicator
}

どうすればこれを達成できますか?

4

4 に答える 4

25

バリアを使用する:

void dispatch_barrier_async(dispatch_queue_t queue, dispatch_block_t block);

非同期実行のためにバリア ブロックを送信し、すぐに戻ります。

バリア ブロックがプライベート同時キューの先頭に到達しても、すぐには実行されません。代わりに、キューは現在実行中のブロックの実行が完了するまで待機します。その時点で、キューはバリア ブロックを単独で実行します。バリア ブロックの後に送信されたブロックは、バリア ブロックが完了するまで実行されません。

この例1 2 3 4 doneは、非同期ですが出力します1 2 4 3 done。アクティビティ インジケーターを処理したいということは理解しているので、これは問題ではありません。

#import <Foundation/Foundation.h>
int main(int argc, char *argv[]) {
    @autoreleasepool {
        dispatch_queue_t queue = dispatch_queue_create("com.myqueue", 0);
        dispatch_sync(queue,  ^(){NSLog(@"1");} );
        dispatch_sync(queue,  ^(){NSLog(@"2");});
        dispatch_async(queue, ^(){NSLog(@"3");});
        dispatch_async(queue, ^(){NSLog(@"4");});
        dispatch_barrier_sync(queue, ^(){NSLog(@"done");});
    }
}

非同期コードをテストするその他の方法については、https ://stackoverflow.com/a/11179523/412916 を参照してください。

于 2012-11-30T21:28:46.957 に答える
5

非同期メソッドがいつ完了したかを実際に知る何らかの方法があると仮定すると、おそらく次のようなものが必要になります。

- (void)syncData {

    // Show activity indicator
    [object sync]; // Synchronous method
    [object2 sync]; // Synchronous method

    _object3Synced = _object4Synced = NO;
    [object3 syncWithCompletionHandler:
          ^{
               _object3Synced = YES;
               [self considerHidingActivityIndicator];
          }]; // Async method
    [object4 syncWithCompletionHandler:
          ^{
               _object4Synced = YES;
               [self considerHidingActivityIndicator];
          }]; // Async method
}

- (void)considerHidingActivityIndicator
{
     if(_object3Synced && _object4Synced)
     {
         // hide activity indicator, etc
     }
}
于 2012-11-30T21:02:21.827 に答える
3

のサブクラスを作成しUIActivityInidicator、プロパティを追加して、activityCount次の 2 つの追加メソッドを実装できます。

- (void)incrementActivityCount
{
    if(_activityCount == 0)
    {
        [self startAnimating];
    }
    _activityCount++;
}

- (void)decrementActivityCount
{
    _activityCount--;
    if(_activityCount <= 0)
    {
        _activityCount = 0;
        [self stopAnimating];
    }
}

これで、アクティビティ カウンター呼び出しを使用する何かを開始するたびincrementActivityCountに、その完了ブロックで (または終了時に) 呼び出しますdecrementActivityCount。これらのメソッドで必要に応じて他のことを行うことができます。上記は単純な例であり、ほとんどの場合 (特に を設定した場合hidesWhenStopped = YES) でおそらく十分です。

于 2012-11-30T21:02:39.550 に答える
0

最初の Async メソッドを起動し、完了ブロックを使用する必要があります。最初の非同期メソッドの完了ブロックで、2 番目の非同期メソッドを起動します。この種の非同期メソッドの使用は無関係になりますが。

于 2012-11-30T20:55:40.227 に答える