4

私は狂ったようにグーグルしていて、まだこれについて混乱しています。

ファイルのURLの配列をディスクにダウンロードしたいのですが、ダウンロード時に各ファイルにロードされたバイト数に基づいてビューを更新したいと思います。私はすでにファイルをダウンロードし、ブロックを介して進行状況と完了を報告するものを持っています。

配列内のファイルごとにこれを行うにはどうすればよいですか?

一度に1つずつ実行しても大丈夫です。この方法で、全体の進捗状況を簡単に計算できます。

float progress = (numCompletedFiles + (currentDownloadedBytes / currentTotalBytes)) / totalFiles)

私は主にGCDとNSOperationsを理解していますが、コールバックが呼び出されるまで待機するように操作またはdispatch_asyncブロックに指示するにはどうすればよいですか?NSOperationをオーバーライドすることで可能と思われますが、それはやり過ぎのようです。別の方法はありますか?GCDだけで可能ですか?

4

3 に答える 3

16

あなたのことを正しく理解しているかどうかはわかりませんが、目的を達成するにはディスパッチ セマフォが必要かもしれません。私のプロジェクトの 1 つで、ディスパッチ セマフォを使用して、別のプレイヤーによる別のターンが完了するまで待機します。これは私が使用したコードの一部です。

for (int i = 0; i < _players.count; i++)
{

    // a semaphore is used to prevent execution until the asynchronous task is completed ...

    dispatch_semaphore_t sema = dispatch_semaphore_create(0);


    // player chooses a card - once card is chosen, animate choice by moving card to center of board ...

    [self.currentPlayer playCardWithPlayedCards:_currentTrick.cards trumpSuit:_trumpSuit completionHandler:^ (WSCard *card) {

        BOOL success = [self.currentTrick addCard:card];

        DLog(@"did add card to trick? %@", success ? @"YES" : @"NO");

        NSString *message = [NSString stringWithFormat:@"Card played by %@", _currentPlayer.name];
        [_messageView setMessage:message];

        [self turnCard:card];
        [self moveCardToCenter:card];


        // send a signal that indicates that this asynchronous task is completed ...

        dispatch_semaphore_signal(sema);

        DLog(@"<<< signal dispatched >>>");
    }];


    // execution is halted, until a signal is received from another thread ...

    DLog(@"<<< wait for signal >>>");

    dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
    dispatch_release(sema);


    DLog(@"<<< signal received >>>");
于 2013-02-04T23:53:37.880 に答える
7

ディスパッチグループは、独立した、または個別に非同期化された一連のブロック/タスクの完了を追跡するように設計されたGCD機能です。

dispatch_group_async()を使用して問題のブロックを送信するか、非同期タスクをトリガーする前にグループをdispatch_group_enter()し、タスクが完了したときにグループをdispatch_group_leave()します。

次に、グループ内のすべてのブロック/タスクが完了したときに、dispatch_group_notify()を介して非同期的に通知を受け取るか、必要に応じて、dispatch_group_wait()を使用して同期的に完了を待つことができます。

于 2013-02-05T06:28:00.833 に答える
0

NSOperation をサブクラス化し、「同時」操作にすることで機能するようになったことに注意したいだけです。(このコンテキストでの同時実行は、完了としてマークする前に待機する必要がある非同期操作を意味します)。

http://www.dribin.org/dave/blog/archives/2009/05/05/concurrent_operations/

基本的に、サブクラスで次のことを行います

  1. オーバーライドstartして操作を開始します
  2. オーバーライドisConcurrentして返すYES
  3. 終了したら、キー値に準拠した方法で isExecuting と isFinished が正しく変更されていることを確認します (基本的に、willChangeValueForKey:and didChangeValueForKey:forisFinishedisExecuting

そして、キューを含むクラスで

  1. に設定maxConcurrentOperationCountNSOperationQueueます1
  2. すべての操作が完了するとトリガーされるすべての同時操作の後に操作を追加します
于 2013-02-05T15:51:24.260 に答える