在iOS多线程开发中,一般常用三种方式进行:
NSThread
GCD
NSOperationQueue
配合NSOperation
子类使用
具体这三类多线程在iOS中是如何开发的在这里就不多说了,不了解的可以上官网或者百度搜索.在GCD
中我们可以创建串行队列,并且加到串行队列上的操作是依次进行的,即先加进去的代码先执行,后加进去的代码后执行.细心的同学可能也发现了在NSOperationQueue
中有一个maxConcurrentOperationCount
属性,该属性可用来设置加入到NSOperationQueue
中可以同时执行的最大操作数量.可能有的小伙伴会问了,设置maxConcurrentOperationCount = 1
,那不就是相当于GCD
中的串行队列了吗?是这样吗?
下面我们就来用代码证实一下,我们向队列中加两个operation,先加入的operation优先级低一些,后加入的operation优先级高一些:
- (void)ceshi
{
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
queue.maxConcurrentOperationCount = 1;
[queue addOperationWithBlock:^{
NSLog(@"第一个任务");
}];
[queue addOperationWithBlock:^{
NSLog(@"第二个任务");
}];
[queue addOperationWithBlock:^{
NSLog(@"第三个任务");
}];
NSBlockOperation *blockOperationOne = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"执行第一个block任务, 当前线程为: %@", [NSThread currentThread]);
}];
blockOperationOne.queuePriority = NSOperationQueuePriorityVeryLow;
NSBlockOperation *blockOperationTwo = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"执行第二个block任务, 当前线程为: %@", [NSThread currentThread]);
}];
blockOperationTwo.queuePriority = NSOperationQueuePriorityVeryHigh;
// [blockOperationOne addDependency:blockOperationTwo];
[queue addOperation:blockOperationOne];
[queue addOperation:blockOperationTwo];
}
控制台打印如下:
2017-09-29 10:16:22.750 ELOperation[25642:794857] 第一个任务
2017-09-29 10:16:22.751 ELOperation[25642:794854] 执行第二个block任务, 当前线程为: <NSThread: 0x600000074340>{number = 3, name = (null)}
2017-09-29 10:16:22.752 ELOperation[25642:794855] 第二个任务
2017-09-29 10:16:22.753 ELOperation[25642:794855] 第三个任务
2017-09-29 10:16:22.753 ELOperation[25642:794854] 执行第一个block任务, 当前线程为: <NSThread: 0x600000074340>{number = 3, name = (null)}
可以看到blockOperationTwo先于blockOperationOne执行,也就是后加入的operation先执行了,原因是我们设置了优先级.再来看一种场景:
- (void)ceshi
{
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
queue.maxConcurrentOperationCount = 1;
[queue addOperationWithBlock:^{
NSLog(@"第一个任务");
}];
[queue addOperationWithBlock:^{
NSLog(@"第二个任务");
}];
[queue addOperationWithBlock:^{
NSLog(@"第三个任务");
}];
NSBlockOperation *blockOperationOne = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"执行第一个block任务, 当前线程为: %@", [NSThread currentThread]);
}];
// blockOperationOne.queuePriority = NSOperationQueuePriorityVeryLow;
NSBlockOperation *blockOperationTwo = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"执行第二个block任务, 当前线程为: %@", [NSThread currentThread]);
}];
// blockOperationTwo.queuePriority = NSOperationQueuePriorityVeryHigh;
[blockOperationOne addDependency:blockOperationTwo];
[queue addOperation:blockOperationOne];
[queue addOperation:blockOperationTwo];
}
执行结果如下:
2017-09-29 10:21:44.559 ELOperation[25661:801126] 第一个任务
2017-09-29 10:21:44.559 ELOperation[25661:801126] 第二个任务
2017-09-29 10:21:44.560 ELOperation[25661:801126] 第三个任务
2017-09-29 10:21:44.562 ELOperation[25661:801144] 执行第二个block任务, 当前线程为: <NSThread: 0x60800006e440>{number = 3, name = (null)}
2017-09-29 10:21:44.563 ELOperation[25661:801126] 执行第一个block任务, 当前线程为: <NSThread: 0x60000006ad00>{number = 4, name = (null)}
在上面的场景中我们设置的operation依赖,同样看到了先加入的operation不一定先执行.到这里你还认为设置maxConcurrentOperationCount = 1
,NSOperationQueue
就成了串行队列了吗?