1、GCD应用 单例模式
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSLog(@"执行一次%@",[NSThread currentThread]);
});
2、GCD延时操作
(1)第一种方式
[self performSelector:@selector(handleAction) withObject:nil afterDelay:0];
(2)第二种方式
DISPATCH_TIME_NOW 从现在开始
delayInSeconds 延迟几秒
dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC));
when dispatch_time_t
dispatch_after(time, dispatch_get_main_queue(), ^{
NSLog(@"%@",[NSThread currentThread]);
});
3、调度组
(1)第一种形式
//创建调度组
dispatch_group_t group = dispatch_group_create();
//获取全局队列
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
//调度组的异步请求
dispatch_group_async(group, queue, ^{
[NSThread sleepForTimeInterval:2];
NSLog(@"下载第一张图");
});
dispatch_group_async(group, queue, ^{
[NSThread sleepForTimeInterval:3];
NSLog(@"下载第二张图");
});
dispatch_group_async(group, queue, ^{
[NSThread sleepForTimeInterval:1];
NSLog(@"下载第三张图");
});
dispatch_group_async(group, queue, ^{
[NSThread sleepForTimeInterval:5];
NSLog(@"下载第四张图");
});
//notify通知,当所有异步请求完成时调用dispatch_group_notify
dispatch_group_notify(group, queue, ^{
NSLog(@"更新UI”);
});
(2)第二种形式
//创建调度组
dispatch_group_t group = dispatch_group_create();
//获取全局队列
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
//进入队列
dispatch_group_enter(group);
dispatch_async(queue, ^{
[NSThread sleepForTimeInterval:2];
NSLog(@"下载第一张图");
//离开队列
dispatch_group_leave(group);
});
dispatch_group_enter(group);
dispatch_async(queue, ^{
[NSThread sleepForTimeInterval:1];
NSLog(@"下载第er张图");
dispatch_group_leave(group);
});
dispatch_group_enter(group);
dispatch_async(queue, ^{
[NSThread sleepForTimeInterval:3];
NSLog(@"下载第san张图");
dispatch_group_leave(group);
});
//等待调度队列wait相当于一个阻塞状态
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
NSLog(@"更新UI”);
(4)中断操作
dispatch_barrier_async一定是自定义队列
这里指定的并发队列应该是自己通过dispatch_queue_create函数创建的。
如果你传的是一个串行队列或者全局并发队列,这个函数等同于dispatch_async函数。
dispatch_queue_t queue = dispatch_queue_create("com.bjsxt", DISPATCH_QUEUE_CONCURRENT); //dispatch_get_global_queue(0, 0);
dispatch_async(queue, ^{
[NSThread sleepForTimeInterval:1];
NSLog(@"1");
});
dispatch_async(queue, ^{
[NSThread sleepForTimeInterval:3];
NSLog(@"2");
});
dispatch_async(queue, ^{
[NSThread sleepForTimeInterval:2];
NSLog(@"3");
});
//中断操作dispatch_barrier_async
dispatch_barrier_async(queue, ^{
NSLog(@"--------");
[NSThread sleepForTimeInterval:1];
});
dispatch_async(queue, ^{
[NSThread sleepForTimeInterval:1];
NSLog(@"4");
});
dispatch_async(queue, ^{
NSLog(@"5”);
});
(7)遍历操作
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
//iterations 遍历的次数
dispatch_apply(5, queue, ^(size_t i) {
NSLog(@"%@",@(i));
});
2、NSOperation基础
(1)创建方式
1)基于一个对象和selector来创建操作。如果你已经有现有的方法来执行需要的任务,就可以使用这个类
NSInvocationOperation * op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downImage) object:nil];
2)能够并发地执行一个或多个block对象,所有相关的block都执行完之后,操作才算完成
NSBlockOperation * op = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"%@",[NSThread currentThread]);
NSLog(@"第一个操作”);
}];
3)获取主队列
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
NSLog(@"%@",[NSThread currentThread]);
NSLog(@"更新UI");
}];
3)如果我们想在一个NSOperation执行完毕后做一些事情,就调用NSOperation的setCompletionBlock方法来设置想做的事情
[op setCompletionBlock:^{ NSLog(@"完成”); }];
4) 通过addExecutionBlock方法添加block操作,开启多个线程
[op addExecutionBlock:^{
NSLog(@"%@",[NSThread currentThread]);
NSLog(@"第二个操作");
}];
(2)开始执行任务
1)一个NSOperation对象可以通过调用start方法来执行任务,默认是同步执行的。
[op start];(同步执行)
2)NSOperation是基于GCD的,把GCD的block封装成opertion,
NSOperationQueue是全局队列封装
将NSOperation添加到一个NSOperationQueue(操作队列)中去执行,而且是异步执行的。
//添加一个block形式的operation
[queue addOperationWithBlock:^{
NSLog(@"op3 - %@",[NSThread currentThread]);
}];
(3)添加任务
NSOperation添加到queue之后,通常短时间内就会得到运行。
waitUntilFinished yes 操作完成后执行下面的代码 no 先执行下面的代码
[queue addOperations:@[op,op2] waitUntilFinished:NO];
self.queue.maxConcurrentOperationCount = 2;
(5)设置依赖关系
//添加NSOperation的依赖对象
[op2 addDependency:op1];
[op3 addDependency:op2];
注意:不能创建环形依赖,如A依赖B,B依赖A,这是错误的
(6)设置优先级
设置优先级,数据量少看不出
op1.queuePriority = -4;
(7)设置挂起状态
暂停一个queue不会导致正在执行的operation在任务中途暂停,只是简单地阻止调度新Operation执行
挂起状态设置
self.queue.suspended = !self.queue.suspended;
(8)取消queue中的操作
1.取消queue中所有的操作
[self.queue cancelAllOperations];
2.取消单个操作
[op cancel];
3、GCD和NSOperation的区别
GCD -- (iOS4.0)多线程解决方案
将任务(block)添加到队列(串行,并行(全局队列)),指定执行任务的方法。(同步,异步)
拿到dispatch_get_main_queue,线程之间的通信
NSOperation -- (iOS2.0) (后经苹果改造)
将操作添加到队列里
[NSOperationQueue mainQueue] 获取主队列,将任务添加到主队列,就会在主线程中执行
NSOperation可以设置最大并发数(用GCD处理,比较麻烦)
可以暂停可以继续,也就是挂起操作
取消所有的任务
设置依赖关系