是的,可以做到这一点,我看到的主要优势是您可以消除对 GCD 的依赖,并使您的大部分代码与您的主要并发技术无关。
我认为启动一个负责管理异步工作单元的调度和协调它们的回调的新类是合理的,而不是将其添加到视图控制器类中。这样的对象以后可以维护自定义调度队列或NSOperationQueue
s 或任何未来的技术出现。我正在想象一个带有默认实例的东西,它还提供一个 API 来调度与底层线程技术无关的块。使用 GCD 的一个可能示例如下:
typedef void(^AsynchronousWorkManagerBlock)();
@interface AsynchronousWorkManager : NSObject
+ (AsynchronousWorkManager *)defaultManager;
- (void)executeInBackground:(AsynchronousWorkManagerBlock)backgroundBlock
withMainThreadCallback:(AsynchronousWorkManagerBlock)callbackBlock;
@end
@implementation AsynchronousWorkManager
+ (AsynchronousWorkManager *)defaultManager
{
static dispatch_once_t onceToken;
static AsynchronousWorkManager *DefaultManager = nil;
dispatch_once(&onceToken, ^{
DefaultManager = [[self alloc] init];
});
return DefaultManager;
}
- (void)executeInBackground:(AsynchronousWorkManagerBlock)backgroundBlock
withMainThreadCallback:(AsynchronousWorkManagerBlock)callbackBlock
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
backgroundBlock();
dispatch_async(dispatch_get_main_queue(), callbackBlock);
});
}
@end
客户端代码可以这样调用它:
[[AsynchronousWorkManager defaultManager] executeInBackground:^{
NSLog(@"This code is happening in the background");
}
withMainThreadCallback:^{
NSLog(@"This code is happening on the main thread");
}];
[[AsynchronousWorkManager defaultManager] executeInBackground:^{
sleep(3);
}
withMainThreadCallback:^{
NSLog(@"Done Sleeping");
}];
稍后,如果您决定改用 usingNSOperationQueue
而不是 GCD,则无需更改 API 即可直接更改,如以下示例实现所示:
@interface AsynchronousWorkManager ()
@property (nonatomic, strong) NSOperationQueue *operationQueue;
@end
@implementation AsynchronousWorkManager
+ (AsynchronousWorkManager *)defaultManager
{
static dispatch_once_t onceToken;
static AsynchronousWorkManager *DefaultManager = nil;
dispatch_once(&onceToken, ^{
DefaultManager = [[self alloc] init];
});
return DefaultManager;
}
- (id)init
{
if (self = [super init]) {
_operationQueue = [[NSOperationQueue alloc] init];
}
return self;
}
- (void)executeInBackground:(AsynchronousWorkManagerBlock)backgroundBlock
withMainThreadCallback:(AsynchronousWorkManagerBlock)callbackBlock
{
NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:backgroundBlock];
blockOperation.completionBlock = ^{ [[NSOperationQueue mainQueue] addOperationWithBlock:callbackBlock]; };
[self.operationQueue addOperation:blockOperation];
}
@end
我不完全确定这是多么必要,但由于它可以在没有太多代码的情况下完成,我认为它可能是值得的,而不仅仅是过度工程的练习。如果您的应用程序广泛使用不同的优先级队列或更专业的 GCD 功能,我会谨慎使用此功能,因为可能会在没有真正获得任何底层实现灵活性的情况下引入泄漏抽象。