BFTaks 的工作更加愉悦的一组有用附加功能。
一个 UIImageView 子类,允许您根据任务设置图像。在分配任务时,它将执行并在完成时更新图像内容。
BFTask* imageTask = [BFTask taskWithResult[UIImage imageNamed:@"name"];
BFTaskImageView* imageView;
imageView.task = imageTask;
允许您创建在某个时间段后过期的任务。对网络操作很有用。任务将以 domain=BFTaskErrorDomain
和 code = kBFTimeoutError
错误。您还可以在 BFTask
中使用便利的 hasTimedOut
属性。有两种方法可以做到这一点
创建一个在设置的时间间隔后过期的 BFTaskCompletionSource
BFTaskCompletionSource *tcs = [BFTaskCompletionSource taskCompletionSourceWithExpiration:1];
[self someAsyncMethodWithCompletion:^(id result){
// need to use trySetResult here because it could have expired!
[tcs trySetResult:result];
}];
现在如果您继续任务,它将在指定的超时时间后完成或取消。
[tcs.task continueWithBlock:^id(BFTask* task){
if(task.hasTimedOut){
//timed out
}
else {
// proceed as normal
}
}];
确保使用 try
方法设置结果或错误来处理原始任务在超时后完成的情况。
如果已经有了一个 BFTask,这是一种比上面的方法更快的操作方式。使用 setTimeout
方法,然后继续使用 continue 块。
BFTask* someTask;
[[someTask setTimeout:20] continueWithBlock: ^id (BFTask *task) {
if (task.hasTimedOut) {
//timed out
}
else {
// proceed as normal
}
return nil;
}];
如果您习惯了使用 blocks,那么每次对 BFTask* 的结果进行类型转换可能会很麻烦,也可能导致错误。如果需要检查取消、异常或其他任务属性,则应使用默认方法,但如果确信返回类型并想快速处理结果和错误情况,这可能会很有用。
BFTask* someTask; // task that returns a string
[someTask continueWithResultBlock:^id(NSString* result, NSError *error) {
//normal handling
return nil;
}];
//success block case:
[someTask imageTask2 continueWithSuccessResultBlock:^id(NSString* result) {
//normal handling
return nil;
}];
还有一些方法接受 BFExecutor 参数。
创建一个新的任务,该任务是给定任务数组之间竞争的结果。当第一个给定的任务完成、失败或取消时,它将完成。灵感来自 javascript 的 Promise.race() 功能。
BFTask* task1;
BFTask* task2;
BFTask* raceTask = [BFTask raceForTasks:@[task1, task2]];
在给定的块期间执行任务的一种简单方法。该块在后台队列中执行。
// example of task during block;
[BFTask taskDuringBlock:^id {
NSURL *url = [NSURL URLWithString:@"x.png"];
NSData *imageData = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:imageData];
return image;
}];
PS:如果您从块中返回一个 NSError
或 NSException
,则结果任务将失败。您还可以返回一个 BFTask
,在这种情况下,结果任务将根据返回的任务的结果进行解决。
等待通知被发布到通知中心的简单方法
[[[NSNotificationCenter defaultCenter] waitForNotificationNamed:UIApplicationDidEnterBackgroundNotification] continueWithSuccessBlock:^id _Nullable(BFTask<NSNotification *> * _Nonnull t) {
// this only listens to notification once then removes observer
return t;
}];
有一种辅助函数可以在一行中设置给定任务源的结果或错误,对于包装具有完成块的函数非常实用
BFTaskCompletionSource* tcs = [BFTaskCompletionSource taskCompletionSource];
[tcs setError:error orResult: result];
还有一个默认的闺房用于包装接受完成块的函数
defaultErrorClosure
defaultResultClosure
.例如,而不是
[self loadStringAsync:^(NSString* result, NSError* error) {
if(error) {
[tcs trySetError: error];
} else {
[tcs trySetResult: result];
}
}];
你可以这样做
[self loadStringsAsync:tcs.defaultResultClosure];
要查看所有这些 任务 一起工作的示例,请查看示例应用程序。
要运行示例项目,先克隆存储库,然后先从示例目录运行 pod install
非常欢迎提供新功能想法、建议或任何一般反馈。
BFTask-Extras 可通过 CocoaPods 获取。要安装它,只需将以下行添加到您的 Podfile 中
pod "BFTask-Extras"
Felix Dumit, [email protected]
BFTask-Extras 在 MIT 许可下可用。有关更多信息,请参阅 LICENSE 文件。