GCD和NSOperation 的概念,用法及之间的区别
Posted 雷坤
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了GCD和NSOperation 的概念,用法及之间的区别相关的知识,希望对你有一定的参考价值。
CGD与NSOperation的区别
gcd是基于c的底层api,NSOperation属于object-c类。
相对于gcd:
1,NSOperation拥有更多的函数可用,具体查看api。
2,在NSOperationQueue中,可以建立各个NSOperation之间的依赖关系。
3,有kvo,可以监测operation是否正在执行(isExecuted)、是否结束(isFinished),是否取消(isCanceld)。
4,NSOperationQueue可以方便的管理并发、NSOperation之间的优先级。
gcd主要与block结合使用。
======================================================
#pragma mark - 使用GCD去创建一个串行队列
// 第一种: 系统提供的创建串行队列方法
// dispatch_queue_t queue = dispatch_get_main_queue();// 在真正的开发中如果需要创建串行队列,比较习惯用这种
// 第二种: 自己去创建
// 参数1: 系统提供的一个宏
// 参数2: 系统的保留字段
// 两个参数的位置没有严格的限定,只要写两个参数即可
// dispatch_queue_t queue = dispatch_queue_create(DISPATCH_QUEUE_SERIAL, 0);serial 串行
#pragma mark -- 使用GCD去创建并行队列
// 第一种方式: 系统的方式
// 参数1: 优先级 (有四个,没有明显的区别)
// 参数2: 系统保留字
// dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
// 第二种方式: 自己创建的
// 参数1: 表示队列的名字
// 参数2: 系统提供的宏
// dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT);//concurrent 并发
//
// dispatch_async(queue, ^{
// NSLog(@"current1 = %@, mainThread = %@", [NSThread currentThread], [NSThread mainThread]);
// });
#pragma mark - 几秒之后去做每一件事
// 参数1:
// 参数2:
// 参数3:
// dispatch_time
// 参数1: 什么时候
// 参数2:
// dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
// NSLog(@"3.0秒时候");
// });
//
#pragma mark - 重复向一个队列中添加多个任务
// dispatch_queue_t queue = dispatch_queue_create(0, DISPATCH_QUEUE_CONCURRENT);// 并行
// // 参数1; 设置的个数
// // 参数2: 队列
// // 参数3: block后加参数名 (index)
//
// dispatch_apply(100, queue, ^(size_t index) {
// NSLog(@"%ld", index);
//
// });
//
#pragma mark - 分组
// // 创建一个分组
// dispatch_group_t group = dispatch_group_create();
//
// // 创建一个并行队列
// dispatch_queue_t queue = dispatch_queue_create(0, DISPATCH_QUEUE_CONCURRENT);
//
// // 创建任务1:
// dispatch_group_async(group, queue, ^{
// NSLog(@"我是任务1");
//
//
//
// });
//
//
// // 创建任务2
// dispatch_group_async(group, queue, ^{
// NSLog(@"我是任务2");
// });
//
// // 用于监听所有任务的执行情况 [所以此功能代码必须放在所有任务之后进行书写]
// dispatch_group_notify(group, queue, ^{
// NSLog(@"我是在所有任务之后执行的");
// });
//
#pragma mark - 并发中的串行 (披着羊皮的狼)
// DISPATCH_QUEUE_SERIAL 串行: 特点: 任务顺序执行
// DISPATCH_QUEUE_CONCURRENT 并行 特点: 无序的
// 创建队列 (串行)
dispatch_queue_t queue = dispatch_queue_create(0, DISPATCH_QUEUE_SERIAL);
// 添加任务
dispatch_async(queue, ^{
NSLog(@"任务1");
});
dispatch_async(queue, ^{
NSLog(@"任务2");
});
dispatch_async(queue, ^{
NSLog(@"任务3");
});
dispatch_async(queue, ^{
NSLog(@"任务4");
});
dispatch_async(queue, ^{
NSLog(@"任务5");
});
[self loadData];
}
- (void)loadData
{
// 创建URL
NSURL *url = [NSURL URLWithString:@"http://www.baidu.com"];
// 创建session
NSURLSession *session = [NSURLSession sharedSession];
// 创建NSRULSessionTask
NSURLSessionTask *task = [session dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (error == nil) {
// 处理数据
// 回到主线程刷新UI
dispatch_async(dispatch_get_main_queue(), ^{
});
}
}];
}
===========================================================
self.imageView = [[UIImageView alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.imageView.backgroundColor = [UIColor redColor];
[self.view addSubview:self.imageView];
// 自己创建的
// dispatch_async(dispatch_queue_create(@"myQueue", DISPATCH_QUEUE_CONCURRENT), <#^(void)block#>)
// 系统方式
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
dispatch_async(queue, ^{
// ======处理数据库=======
// 创建URL===
NSURL *url = [NSURL URLWithString:@"http://img2.3lian.com/2014/f6/127/d/39.jpg"];
// 转换成数据
NSData *data = [[NSData alloc] initWithContentsOfURL:url];
// 初始化
UIImage *image = [[UIImage alloc] initWithData:data];
if (data != nil) {
dispatch_async(dispatch_get_main_queue(), ^{
// =====刷新界面======
self.imageView.image = image;
});
}
NSLog(@"current1 = %@, mainThread = %@", [NSThread currentThread], [NSThread mainThread]);
});
=========================================================================-
NSOperationQueue的用法
(void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// NSOperation不能直接进行多线程的创建,需要借助 :NSOperationQueue
// 使用NSOperation的第一个子类去创建子线程 :NSInvocationOperation
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(test) object:nil];
// 在单独使用子NSOperation的子类去创建线程的时候,一定要启动
// [operation start];
// 在使用NSOperation的子类去创建线程的时候,实际上线程没有真正意义上的创建
// 使用NSOperation的第二个子类创建线程
NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"我是block");
NSLog(@"======currentThread == %@", [NSThread currentThread]);
NSLog(@"=====%@", [NSThread mainThread]);
}];
// 只有启动的时候才会调用block中的内容
//[blockOperation start];
// 需要把上面的两个线程,放到操作队列里
// addOperation一旦创建的对象加入到操作对列中,就不能调用start,否则会崩溃
// NSOperationQueue *queue = [[NSOperationQueue alloc] init];
// [queue addOperation:operation];
// [queue addOperation:blockOperation];
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
// 创建队列的对象
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
// 最大的并发数量值
// 当值设置为1的时候,可以叫做串行: 即顺序执行
// 当值设置大于1的时候,叫做并行: 多条通道同时进行各自的任务
queue.maxConcurrentOperationCount = 2;
for (int i = 0; i < 10; i++) {
NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"++++++currentThread == %@", [NSThread currentThread]);
NSLog(@"++++++mainThread == %@", [NSThread mainThread]);
NSLog(@"===%d", i);
}];
[queue addOperation:blockOperation];
}
}
- (void)test
{
NSLog(@"??????");
NSLog(@"currentThread == %@", [NSThread currentThread]);
NSLog(@"mainThread == %@", [NSThread mainThread]);
}
=========================================================
以上是关于GCD和NSOperation 的概念,用法及之间的区别的主要内容,如果未能解决你的问题,请参考以下文章