实现可以在 Bolts Framework 中取消的任务 (BFTask)
Implementing tasks that can be canceled in Bolts Framework (BFTask)
BFTask
对我很好,但我有一个抱怨:我还没有看到您应该如何 cancel
一项任务的工作示例。关于这个主题的全部文档都可以在 their GitHub page 上找到,只有一个低级部分包含了除我关心的部分之外的所有内容:如何 取消任务。
// Somewhere else.
MYCancellationToken *cancellationToken = [[MYCancellationToken alloc] init];
[obj doSomethingComplicatedAsync:cancellationToken];
// When you get bored...
[cancellationToken cancel];
他们的代码片段后面是:
Note: The cancellation token implementation should be thread-safe.
我想知道以下问题:
- 他们没有在
BFTask
接口本身上提供 cancel
方法是否有充分的理由?他们有一个 属性 表示任务是否被取消但没有办法取消它。
- 他们不在
BFTask
本身上包含 cancellationToken(s)
属性 有充分的理由吗?
cancel
的实施是否与任务本身紧密相关?或者是否可以像 cancelAllOperations
的 NSOperationQueue
? 这样的一般实现
- 如您所知,
BFTask
是 Future and Promises 结构的一个实现:
"a future is a read-only placeholder view of a variable, while a promise is a writable, single assignment container which sets the value of the future".
基本上,BFTask
是 Future
:它是变量的只读占位符视图。
BFTaskCompletionSource
是一个承诺:它是一个可写的、单一的赋值容器,它设置了未来的值。 (或错误 - 或取消任务)
BFTask
public界面保持只读状态,因此不允许直接取消。
- 这与上一个问题的答案相同:BFTask是只读的,代表一个只读值。公开取消令牌将允许您操纵任务,这与其性质相矛盾。
- 一起来看看:https://github.com/BoltsFramework/Bolts-iOS/blob/master/Bolts/Common/BFCancellationToken.m
BFCancellationToken
令牌仅存储一个状态,BFTask
可以检查该状态。您的异步任务代码基本上可以定期检查 cancellationRequested
是否设置为 true,这允许您手动取消您的任务。
注意:Bolts 框架 iOS docs 说:"A task is kind of like a JavaScript Promise" 这可能会造成混淆,因为它确实是一个 Future。我认为它只是在其 Javascript 起源中被命名为错误。
使用[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];
Bolts 中有一个相当有用的取消标记实现,但出于某种原因,在头文件之外根本没有记录它。关键是BFCancellationTokenSource
的用法。您需要保留对 BFCancellationTokenSource
的引用才能发出和取消 BFCancellationToken
.
在我的示例中,我有一个名为 cancellableFunction()
的特定函数,它连续发出一堆任务。如果在最后一次调用完成之前再次调用该函数,我希望取消上一次调用未完成的任务。
这里的关键是将 token
传递到每个 continueWith
函数调用中。如果在任何时候 token
通过 tokenSource
取消,未到达的 successBlock
将不会被执行。您还可以通过每个 BFContinuationBlock
中的 task.cancelled
检查取消状态(显然在成功块中将为 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)
}
...
}
BFTask
对我很好,但我有一个抱怨:我还没有看到您应该如何 cancel
一项任务的工作示例。关于这个主题的全部文档都可以在 their GitHub page 上找到,只有一个低级部分包含了除我关心的部分之外的所有内容:如何 取消任务。
// Somewhere else.
MYCancellationToken *cancellationToken = [[MYCancellationToken alloc] init];
[obj doSomethingComplicatedAsync:cancellationToken];
// When you get bored...
[cancellationToken cancel];
他们的代码片段后面是:
Note: The cancellation token implementation should be thread-safe.
我想知道以下问题:
- 他们没有在
BFTask
接口本身上提供cancel
方法是否有充分的理由?他们有一个 属性 表示任务是否被取消但没有办法取消它。 - 他们不在
BFTask
本身上包含cancellationToken(s)
属性 有充分的理由吗? cancel
的实施是否与任务本身紧密相关?或者是否可以像cancelAllOperations
的NSOperationQueue
? 这样的一般实现
- 如您所知,
BFTask
是 Future and Promises 结构的一个实现:
"a future is a read-only placeholder view of a variable, while a promise is a writable, single assignment container which sets the value of the future".
基本上,BFTask
是Future
:它是变量的只读占位符视图。
BFTaskCompletionSource
是一个承诺:它是一个可写的、单一的赋值容器,它设置了未来的值。 (或错误 - 或取消任务)
BFTask
public界面保持只读状态,因此不允许直接取消。 - 这与上一个问题的答案相同:BFTask是只读的,代表一个只读值。公开取消令牌将允许您操纵任务,这与其性质相矛盾。
- 一起来看看:https://github.com/BoltsFramework/Bolts-iOS/blob/master/Bolts/Common/BFCancellationToken.m
BFCancellationToken
令牌仅存储一个状态,BFTask
可以检查该状态。您的异步任务代码基本上可以定期检查cancellationRequested
是否设置为 true,这允许您手动取消您的任务。
注意:Bolts 框架 iOS docs 说:"A task is kind of like a JavaScript Promise" 这可能会造成混淆,因为它确实是一个 Future。我认为它只是在其 Javascript 起源中被命名为错误。
使用[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];
Bolts 中有一个相当有用的取消标记实现,但出于某种原因,在头文件之外根本没有记录它。关键是BFCancellationTokenSource
的用法。您需要保留对 BFCancellationTokenSource
的引用才能发出和取消 BFCancellationToken
.
在我的示例中,我有一个名为 cancellableFunction()
的特定函数,它连续发出一堆任务。如果在最后一次调用完成之前再次调用该函数,我希望取消上一次调用未完成的任务。
这里的关键是将 token
传递到每个 continueWith
函数调用中。如果在任何时候 token
通过 tokenSource
取消,未到达的 successBlock
将不会被执行。您还可以通过每个 BFContinuationBlock
中的 task.cancelled
检查取消状态(显然在成功块中将为 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)
}
...
}