在Bolts Framework中实现可以取消的任务(BFTask)

tac*_*cos 7 nsoperation ios bolts-framework bftask

BFTask我一直很好,但我有一个抱怨:​​我还没有看到一个关于你应该如何cancel完成任务的实例.关于这个主题的整个文档可以在他们的GitHub页面找到,其中包含一个简短的部分,其中包括我关心的部分:如何取消任务.

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

// When you get bored...
[cancellationToken cancel];
Run Code Online (Sandbox Code Playgroud)

他们的代码片段后跟:

注意:取消令牌实现应该是线程安全的.

我想知道以下内容:

  1. 有没有充分的理由说他们可能没有cancelBFTask界面本身提供方法?他们有一个属性,表示任务是否被取消,但没有办法取消它.
  2. 有没有充分的理由说他们不会cancellationToken(s)BFTask自己身上加入财产?
  3. 执行是否与cancel任务本身强烈耦合?或者是一般的实现成为可能作为的情况cancelAllOperationsNSOperationQueue

Ken*_*ndt 7

  1. 您可能知道,Future和Promises构造BFTask的实现是:"future是变量的只读占位符视图,而promise是可写的,单个赋值容器,用于设置未来的值". 基本上,a 是:它是变量的只读占位符视图. A 是一个承诺:它是一个可写的单一分配容器,用于设置未来的价值.(或错误-或取消任务) 的公共接口仍然是只读的,所以它不会让你直接取消它.

    BFTaskFuture
    BFTaskCompletionSource
    BFTask
  2. 这与前一个问题的答案相同:BFTask是只读的,表示只读值.公开取消令牌将允许您操纵任务,这与其性质相矛盾.
  3. 让我们来看看它:https://github.com/BoltsFramework/Bolts-iOS/blob/master/Bolts/Common/BFCancellationToken.mBFCancellationToken令牌只是存储状态,而其BFTask可以检查.您的异步任务代码基本上可以定期检查cancellationRequested设置为true,这允许您手动取消您的任务.

    注意:Bolts框架iOS 文档说:"任务有点像JavaScript承诺",这可能令人困惑,因为它确实是一个未来.我认为它的Javascript起源只是错误的.


Har*_*rel 7

在Bolts中有一个非常有用的取消令牌实现,但由于某些原因,它不会在头文件之外的任何文档中记录.关键是使用BFCancellationTokenSource.你需要保留对它的引用BFCancellationTokenSource才能发出和取消BFCancellationToken.

在我的例子中,我有一个特殊的函数cancellableFunction(),它会连续发出一堆任务.如果在最后一次调用完成之前再次调用该函数,我希望取消上一次调用的未完成任务.

这里的关键是传递给token每个continueWith函数调用.如果在任何时候token通过tokenSource,取消,successBlock则不会执行未到达的s.您还可以task.cancelled在每个中检查取消的状态BFContinuationBlock(在成功块中显然是假的).

这是一个例子:

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)
   }

   ...

}
Run Code Online (Sandbox Code Playgroud)