GCD和NSOperation NSOperationQueue的比较
- GCD是c语言实现的一套API,是一种轻量级的实现多线程的方法。队列中执行的是由block构成的任务。
-
优点
1.在多核CPU上线程切换时间快,效率相对高
2.结合block使用比较高效
-
缺点
1.无法停止加入队列的block
2.只能区分不同任务队列的优先级,区分block任务的优先级不易
3.设置依赖关系麻烦
-
-
NSOperation和NSOperationQueues是面向对象的方式。
-
优点
1.可以随时取消准备要执行的任务(任务开始之后就无法阻止了)
2.可以方便设置两个操作的依赖关系
3.可以应用KVO,去监听一个操作是否取消或者完成
4.可以设置操作的优先级,是队列中的任务分优先级的执行
-
缺点
1.性能方面逊于GCD
-
NSOperation的API使用方法
1.继承NSOperation
2.重写“main”函数
3.在“main”函数中建立“autoreleasepool”(你不能获取主线程的自动释放池)
4.把代码放入“autoreleasepool”
方法:
- 取消 cancel:
- [test_operation cancel];
- 开始 start
- [test_operation start];
- 如果在队列中添加一个操作,然后这个队列执行start, 然后这个操作的main函数会执行相应的操作。 如果你在NSOperarion的实例上执行一个操作,没有加入队列,那么操作会在main loop中执行
- 依赖 dependency
- [test1Op addDependency: test2Op];
- [test1Op removeDependency: test2Op]
- 优先级
- [test1Op setQueuePriority:NSOperationQueuePriorityVeryLow]
优先级可以设定的值
NSOperationQueuePriorityLow
NSOperationQueuePriorityNormal
NSOperationQueuePriorityHigh
NSOperationQueuePriorityVeryHigh
当队列中有多个操作时,执行顺序会按照优先级排序,如果两个优先级相同,则按添加多队列中的顺序进行执行。
- Completion block
- 如果你有一些事情要在操作执行完毕后做, 你可以把这些放入block,并且传入这个方法中。注:不会确保这个block在主线程执行。[test1Op setCompletionBlock: ^{ "block" }];
注意的点
- 如果你要给操作传入一些值或者指针,最好的方法是创建你自己的初始化方法。
- 如果你的操作有返回值或者对象,好的方式是声明代理方法。通常你想在主线程回调代理方法。
- 你不可以重新给操作排队,一旦操作加入队列,你就放弃了所有权。如果你想再次使用相同的操作,你应该创建一个新实例
- 如果你要取消一个操作,他不会马上发生。他会在未来检查 isCancelled == YES 的时候被调用,否则,他会一直执行直到完成操作。
- 无论操作是否成功完成,或者是被取消。 isFinished都将返回YES。
NSOperationQueue API使用
NSOperationQueue 不需要你继承,或者重载任何方法。你直接创建一个对象。最好是给你的队列起一个名字以方便你运行的时候识别以及调试。
方法及属性:
- 并行操作:一个队列有好多个线程,队列中的每个操作在自己的线程中运行。
- 并行操作的最大数:
- myQueue.MaxConcurrentOperationCount = 3;
- 如果要恢复到默认值 myQueue.MaxConcurrentOperationCount = NSOperationQueueDefaultMaxConcurrentOperationCount;
- 添加操作:
- [myQueue addOperation: downloadOp];
- 未执行的操作:
- NSArray *active_and_pending_operations = myQueue.operations;
- NSInteger count_of_operations = myQueue.operationCount;
- 暂停/恢复队列:
- [myQueue setSuspended:YES];
- [myQueue setSuspended:NO];
- 取消操作:
- [myQueue cancelAllOperations];
- 建立对Block的操作:
建立block的例子:
__weak MyViewController *weakSelf = self;
// Add an operation as a block to a queue
[myQueue addOperationWithBlock: ^ {
NSURL *aURL = [NSURL URLWithString:@"http://www.somewhere.com/image.png"];
NSError *error = nil;
NSData *data = [NSData dataWithContentsOfURL:aURL options:nil error:&error];
UIImage *image = nil;
If (data)
image = [UIImage imageWithData:data];
// Update UI on the main thread.
[[NSOperationQueue mainQueue] addOperationWithBlock: ^ {
weakSelf.imageView.image = image;
}];
网友评论