我目前正在使用GCD。但是,我听说NSOperation
实际上是一个更高级别的计划。但它要复杂得多。
在GCD中,在后台做一些事情就是使用我创建的辅助函数:
+(void)doForeGround:(void (^)())block
{
dispatch_async(dispatch_get_main_queue(), ^{
block();
});
}
+(void)doBackground:(void (^)())block
{
//DISPATCH_QUEUE_PRIORITY_HIGH
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW,0), ^{
//dispatch_async(dispatch_get_global_queue(-2,0), ^{
block();
});
}
-(void)doBackGround:(void (^)())block onComletion:(void (^)())onCompletion
{
[BGHPTools doBackground:^{
block();
[BGHPTools doForeGround:^{
onCompletion();
}];
}];
}
使用NSOperation
进行此操作会更简单吗?
我错过了什么吗?我如何在NSoperation上做同样的事情?
答案 0 :(得分:6)
您可以使用NSOperation
执行与GCD相同的操作。主要区别在于NSOperation
提供了额外的功能。
例如:
NSOperation
有-cancel
方法。派遣队列没有取消的概念;队列中排队的所有块都将运行完毕。NSOperationQueue
具有maximumConcurrentOperationCount
属性,您可以使用(例如)仅允许一次运行3个操作。派遣队列没有这样的概念;它们是串行的,一次只允许1个块,或者并发,允许libdispatch
根据CPU使用率和可用性认为可行。{/ li>
NSOperation
可以依赖于其他NSOperation
,允许您推迟执行特定操作,直到其所有依赖项都已运行。在依赖操作等待时,将允许其他操作在队列中“跳转”。调度队列始终以严格的FIFO顺序出列。 (您可以使用dispatch_group
API模仿依赖关系,但这确实是针对不同类型的问题。)现在,如果你没有使用任何这些功能,GCD工作得很好。使用GCD本身没有错误。只是NSOperation为一些额外的好功能提供了一个方便的包装。
以下是使用NSOperationQueue
重写上述示例的方法:
+(void)doForeground:(void (^)())block
{
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
NSLog(@"I'm running on the main thread!");
block();
}];
}
+(void)doBackground:(void (^)())block
{
// Note; rather than allocating a new NSOperationQueue every time, you could
// allocate the queue once and just refer to that queue. For simplicity, I'll
// skip that here.
[[NSOperationQueue new] addOperationWithBlock:^{
NSLog(@"I'm running asynchronously on whatever thread NSOperationQueue wants!");
block();
}];
}
-(void)doBackground:(void (^)())block onCompletion:(void (^)())onCompletion
{
[[NSOperationQueue new] addOperationWithBlock:^{
block();
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
onCompletion();
}];
}];
}
答案 1 :(得分:4)
比较的操作队列示例:
- (void)viewDidLoad
{
// ...
self.queue = [[NSOperationQueue alloc] init];
// ...
}
- (void)job
{
// background activities ...
}
- (void)startJob
{
NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self
selector:@selector(job)
object:nil];
[self.queue addOperation:op];
}