解决此问题的另一种方法可能如下:为异步任务创建一个辅助对象,并在调用该任务时复制一个完成块。异步任务完成后,使用委托方法调用完成块。因此,我们可能会按如下顺序执行任务:
FSTask *taskA = [FSTask taskWithName:@"Task A"];
FSAsyncTask *taskB = [FSAsyncTask asyncTaskWithName:@"Task B"];
FSTask *taskC = [FSTask taskWithName:@"Task C"];
[taskA performTaskWithCompletionBlock:^ (NSString *result) {
NSLog(@"%@", result);
[taskB performTaskWithCompletionBlock:^ (NSString *result) {
NSLog(@"%@", result);
[taskC performTaskWithCompletionBlock:^ (NSString *result) {
NSLog(@"%@", result);
}];
}];
}];
那么这是如何实现的呢?好吧,看看下面的任务对象......
FSTask.m -主线程上的同步工作......
@interface FSTask ()
@property (nonatomic, copy) NSString *name;
@end
@implementation FSTask
@synthesize name = _name;
+ (FSTask *)taskWithName:(NSString *)name
{
FSTask *task = [[FSTask alloc] init];
if (task)
{
task.name = name;
}
return task;
}
- (void)performTaskWithCompletionBlock:(void (^)(NSString *taskResult))block
{
NSString *message = [NSString stringWithFormat:@"%@: doing work on main thread ...", _name];
NSLog(@"%@", message);
if (block)
{
NSString *result = [NSString stringWithFormat:@"%@: result", _name];
block(result);
}
}
@end
FSAsyncTask.m -后台线程上的异步工作...
@interface FSAsyncTask ()
@property (nonatomic, copy) void (^block)(NSString *taskResult);
@property (nonatomic, copy) NSString *name;
- (void)performAsyncTask;
@end
@implementation FSAsyncTask
@synthesize block = _block;
@synthesize name = _name;
+ (FSAsyncTask *)asyncTaskWithName:(NSString *)name
{
FSAsyncTask *task = [[FSAsyncTask alloc] init];
if (task)
{
task.name = name;
}
return task;
}
- (void)performTaskWithCompletionBlock:(void (^)(NSString *taskResult))block
{
self.block = block;
// the call below could be e.g. a NSURLConnection that's being opened,
// in this case a NSURLConnectionDelegate method will return the result
// in this delegate method the completion block could be called ...
dispatch_queue_t queue = dispatch_queue_create("com.example.asynctask", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^ {
[self performAsyncTask];
});
}
#pragma mark - Private
- (void)performAsyncTask
{
for (int i = 0; i < 5; i++)
{
NSString *message = [NSString stringWithFormat:@"%d - %@: doing work on background thread ...", i, _name];
NSLog(@"%@", message);
[NSThread sleepForTimeInterval:1];
}
// this completion block might be called from your delegate methods ...
if (_block)
{
dispatch_async(dispatch_get_main_queue(), ^ {
NSString *result = [NSString stringWithFormat:@"%@: result", _name];
_block(result);
});
}
}
@end