7

BFTaskは私にとっては良かったのですが、1 つ不満がcancelあります。タスクをどのように行うべきかを示す実際の例をまだ見たことがありません。この件に関するドキュメント全体は、彼らの GitHub ページにあり、私が気にかけている部分以外のすべてを含む単一の低レベルのセクションがあります:タスクをキャンセルする方法.

// Somewhere else.
MYCancellationToken *cancellationToken = [[MYCancellationToken alloc] init];
[obj doSomethingComplicatedAsync:cancellationToken];

// When you get bored...
[cancellationToken cancel];

彼らのコード スニペットの後には、次のものが続きます。

注: キャンセル トークンの実装は、スレッドセーフである必要があります。

私は次のことを疑問に思っています:

  1. インターフェイス自体でcancelメソッドを提供していない可能性がある正当な理由はありますか? BFTaskタスクがキャンセルされたかどうかを表すプロパティがありますが、キャンセルする手段はありません。
  2. それ自体にcancellationToken(s)プロパティを含めない正当な理由はありますか?BFTask
  3. の実装はcancel、タスク自体に強く結合されていますか? または、の場合のように一般的な実装は可能cancelAllOperationsですNSOperationQueueか?
4

3 に答える 3

7

Bolts にはかなり便利なキャンセル トークンの実装がありますが、何らかの理由で、ヘッダー ファイル以外にはまったく文書化されていません。の使い方がポイントですBFCancellationTokenSourceBFCancellationTokenSourceを発行およびキャンセルするには、 への参照を保持する必要がありますBFCancellationToken

私の例ではcancellableFunction()、一連のタスクを連続して発行する特定の関数が呼び出されています。最後の呼び出しが完了する前に関数が再度呼び出された場合、前の呼び出しの未完了のタスクをキャンセルしたい。

ここで重要なのは、tokencontinueWith関数呼び出しに を渡すことです。を介して がいつでもtokenキャンセルされた場合tokenSource、未到達successBlockの は実行されません。task.cancelledそれぞれでキャンセルのステータスを確認することもできますBFContinuationBlock(成功ブロックでは明らかに false になります)。

次に例を示します。

class ViewController: UIViewController {

   ...

   // instance reference to tokenSource so that it can be cancelled by any function in the ViewController
   var tokenSource: BFCancellationTokenSource?

   ...

   func cancellableFunction() -> BFTask {

      // First cancel the previous token
      tokenSource?.cancel()
      // Replace the previous TokenSource with a new one
      tokenSource = BFCancellationTokenSource()
      // Issue new Token from the new TokenSource
      let token = tokenSource!.token

      return functionThatReturnsBFTask().continueWithSuccessBlock({ (task:BFTask) -> AnyObject? in

         ...

         return nil
      }, cancellationToken: token).continueWithExecutor(BFExecutor.mainThreadExecutor(), successBlock: { (task:BFTask) -> AnyObject? in

         ...

         return nil
      }, cancellationToken: token).continueWithBlock({ (task:BFTask) -> AnyObject? in

         // Here you can perform an actions you want to take on cancellation
         if task.cancelled {

         }

         ...

         return nil
      }, cancellationToken: token)
   }

   ...

}
于 2016-03-18T02:36:20.490 に答える
3

コードを使用[self.bfTaskCancelationToken cancel];してシリーズ BFTask をキャンセルする

BFCancellationTokenSource の登録

self.bfTaskCancelationToken = [BFCancellationTokenSource cancellationTokenSource];
[self.bfTaskCancelationToken.token registerCancellationObserverWithBlock:^{
    NSLog(@"task hasbeen Cancelled.....");
    //Do stuff on cancelation task

} ];

シリーズ BFTask を実装する

注:cancellationToken:self.bfTaskCancelationToken.token 後にコードがあります[task continueWithBlock:^id(BFTask *task)

  [[[self showAlertProgressHud] continueWithBlock:^id(BFTask *taskLog) {


            BFTask *task = [BFTask taskWithResult:nil];
            for (int i=0; i<self.arrAssetPhotos.count; i++) {

                AIAssetPhoto *assetPhoto = self.arrAssetPhotos[i];
                task = [task continueWithBlock:^id(BFTask *task) {
                    // Return a task that will be marked as completed.
                    return [self processOnAssetPhoto:assetPhoto index:i completion:NULL];
                } cancellationToken:self.bfTaskCancelationToken.token];

            }

            return task;


        }] continueWithBlock:^id(BFTask *task) {

            // all asset photos process are done.
            return nil;
        }];

連続BFタスクをキャンセルするには?

  //just by calling one simple method 
  [self.bfTaskCancelationToken cancel];
于 2015-11-21T12:57:50.980 に答える