GCD:
创建任务,添加到队列,GCD自动分发任务
-
同步/异步
- 同步任务,异步任务的区别: 线程是否要等待任务结束,同步会阻塞当前线程,直到任务完成
- 同步异步是形容任务/函数
- 同步提交任务 :
dispatch_sync
会等待任务执行完成才会返回---注意是否会死锁 - 异步提交任务 :
dispatch_async
不会等待任务执行完成才返回
- 串行/并行
- 串行队列,队列里面的任务按顺序执行
- 并发队列
创建队列
DISPATCH_QUEUE_SERIAL 串行
DISPATCH_QUEUE_CONCURRENT 并发
-(void)createQueue {
//并发队列
dispatch_queue_t concurrentQueue = dispatch_queue_creat("cry.queue", DISPATCH_QUEUE_CONCURRENT);
dispatch_asyn(concurrentQueue, ^ {
//添加任务1
});
dispatch_asyn(concurrentQueue, ^ {
//添加任务2
});
dispatch_queue_t serialQueue = dispatch_queue_creat("cry.serialqueue", DISPATCH_QUEUE_CONCURRENT);
dispatch_asyn(serialQueue, ^ {
//添加任务1
});
dispatch_asyn(serialQueue, ^ {
//添加任务2
});
}
系统队列
-
GlobalQueue 全局队列
-
四个优先级
- DISPATCH_QUEUE_PRIORITY_HIGH 高优先级
- DISPATCH_QUEUE_PRIORITY_DEFAULT 默认
- DISPATCH_QUEUE_PRIORITY_LOW 低优先级
- DISPATCH_QUEUE_PRIORITY_BACKGROUND 后台
-
MainQueue 主队列
group
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_queue_create("frankfan.queu3", DISPATCH_QUEUE_CONCURRENT);
//添加任务
dispatch_group_async(group, queue, ^{
NSLog(@"1");
});
//group中的队列全部完成后执行(监控)
dispatch_group_notify(group, queue, ^{
NSLog(@"done");
});
//并发队列里加入异步方法,手动添加enter和leave
dispatch_group_async(group, queue, ^{
dispatch_group_enter(group);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"2");
dispatch_group_leave(group);
});
});
dispatch_group_async(group, queue, ^{
NSLog(@"3");
});
dispatch_group_async(group, queue, ^{
NSLog(@"4");
});
dispatch_group_async(group, queue, ^{
NSLog(@"5");
});
无法添加依赖,但是可以添加栅栏
dispatch_barrier_async
dispatch_async(queue, ^{
NSLog(@"1");
});
dispatch_async(queue, ^{
NSLog(@"2");
});
//barrier栅栏
dispatch_barrier_async(queue, ^{
NSLog(@"barrier");
});
dispatch_async(queue, ^{
NSLog(@"3");
});
//3一定在 1和2之后打印,1与2的顺序不定
-
dispatch_once_t
(保证只执行一次---可以单例类中保护对象的创建过程)
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
//只执行一次
});
死锁(在当前线程同步地当前线程添加任务)
最简单的例子:
- (void)demo {
//当前线程是主线程
//获得主线程 mainQueue
dispatch_queue_t mainQueue = dispatch_get_main_queue();
//使用同步方法给队列添加任务
//同步方法: dispatch_sync 队列: mainQueue
dispatch_sync(mainQueue, ^{
NSLog(@"hello");
});
NSLog(@"world");
//hello 和world 都不会答应
//dispatch_sync要等block执行完,主线程才能继续执行
//当前block添加到了主队列里,但是无法得到执行,因为dispatch_sync在等待block执行,阻塞了线程
//因此两者在互相等待,得不到解决
}
NSOperation
- NSOperationQueue 队列
- NSoperation 操作/任务
- (void)NSOperation {
//获得主队列
NSOperationQueue *mainQueue = [NSOperationQueue MainQueue];
//创建队列
NSOperationQueue *queue = [NSOperationQueue new];
//往队列中添加任务
[queue addOperationWithBlock:^ {
//dosomething
}];
//往主线程队列添加任务
[NSBlockOperation *blockOp1 = [NSBlockOperation blockOperationWithBlock:^{
//dosomething
}];
[mainQueue addOperation: blockOp1];
}
- 可以添加多个任务
- 创建的队列里任务是并发的
- 可以通过控制最大任务并发数为1
queue.maxCurrentOperationCount = 1
将队列修改成串行 - 可以添加依赖关系
- 任务可以取消(正在执行的不可以取消)
- 可以添加观察ready/executing/finished
(void)demofun {
NSOperationQueue *queue = [NSOperationQueue new];
NSBlockOperation *blcO1 = [NSBlockOperation blockOperationWithBlock: ^{
//任务1
}];
NSBlockOperation *blcO2 = [NSBlockOperation blockOperationWithBlock: ^{
//任务2
}];
[queue addOperations: @[blc01,blcO2] waitUntilFinished:NO];
//添加依赖,blc02 必须等 blc01执行完
[blc02 addDependency:blc01];
}
NSThread
- 比较麻烦,很少使用实现多线程
- 几个简便的类方法
- (void)demo {
//当前线程
NSThread *currentThread = [NSThread currentThread];
//退出线程
[NSThread exit];
//当前线程休眠3s
[NSThread sleepForTmeInterval:3];
//获取主线程
NSThread *mainTread = [NSThread mainThread];
//判断是否是主线程
[NSThread isMainThread];
//创建线程,执行xx方法
[NSThread detachNewThreadSelector:@selector(doSomething)
toTarget:self withObject:nil];
//NSThread简便方法(NSObject的类别)
//当主线程执行xx方法
[self performSelectorOnMainThread:@selector(doSomething) withObject:nil waitUntilDone: YES];
//在子线程执行xx方法
[self performSelectorInBackground: @selector(doSomething) withObject:nil];
//当前线程同步执行xx方法
[self performSelector:@selecotr(doSomething) withObject:nil];
//取消还没执行的任务
[NSObject cancelPreviousPerformRequestsWithTarget:self];
}