dispatch_object_t
GCD
全部类的基类 dispatch_object_t
是一个联合体(并且是一个透明联合体),就是dispatch_object_t
能够是结构体中的任意一种类型,大小为这些数据类型中最大的数据类型的大小_os_object_s
dispatch_object_s
dispatch_continuation_s
dispatch_continuation_s
结构体主要封装block
和function
,dispatch_async
中的block
最终都会封装成这个数据类型 dispatch_group_s
dispatch_queue_s
dispatch_queue_create
源码libdispatch.dylib
库中,而后下载libdispatch.dylib
源码搜索dispatch_queue_create
能够找到_dispatch_lane_create_with_target
函数来实现建立_dispatch_lane_create_with_target
源码_dispatch_get_root_queue
方法获取目标队列_dispatch_get_root_queue(0, true)
函数获取目标队列,获取到的目标队列是_dispatch_root_queues[DISPATCH_ROOT_QUEUE_IDX_DEFAULT_OVERCOMMIT_PRIORITY]
。_dispatch_get_root_queue(0, false)
函数获取目标队列,获取到的目标队列是_dispatch_root_queues[DISPATCH_ROOT_QUEUE_IDX_DEFAULT_PRIORITY]
。_dispatch_object_alloc
开辟空间建立队列_dispatch_queue_init
初始化队列,这里根据第一步规范后的参数判断设置最大并发数,DISPATCH_QUEUE_WIDTH_MAX
从这里也能够知道最大的并发数是4094_dispatch_continuation_init
任务包装函数_dispatch_continuation_init_f
函数赋值func、ctxt等参数 _dispatch_continuation_async
并发处理函数dx_push
发现是个宏#define dx_push(x, y, z) dx_vtable(x)->dq_push(x, y, z)
,发现仍是调用了dq_push
方法继续全局搜索dq_push
dq_push
方法有不少个不过每一个上面有类型不难猜想异步函数应该对应的是queue_concurrent
下的方法对应的方法是_dispatch_lane_concurrent_push
这里能够经过下符号断点来验证首先如今异步函数钱下个断点_dispatch_lane_concurrent_push
的方法堆栈上因此也验证了上述猜测_dispatch_lane_concurrent_push
_dispatch_continuation_redirect_push
方法这里也能够经过添加符号断点来验证_dispatch_lane_concurrent_push
方法执行完成以后直接进入到_dispatch_continuation_redirect_push
方法而后就执行了任务继续全局搜索_dispatch_continuation_redirect_push
方法dq_push
对应的就不是_dispatch_lane_concurrent_push
方法了由于对应的队列类型变成了跟队列,因此此时应该对应的是_dispatch_root_queue_push
方法一样的也能够根据上述的步骤下一个符号断点来验证,继续全局搜索_dispatch_root_queue_push
方法_dispatch_root_queue_push_override
符号断点在下一个_dispatch_root_queue_push_inline
符号断点发现会走到_dispatch_root_queue_push_override
方法中而后_dispatch_root_queue_push_inline
方法_dispatch_root_queue_poke
方法_dispatch_root_queue_poke_slow
方法_dispatch_root_queues_init
方法点进去发现发现是dispatch_once_f
方法调用func
是_dispatch_root_queues_init_once
_dispatch_worker_thread2
(线程的执行是系统底层去出发的,这里只须要绑定线程,系统会去触发线程)方法查看源码_dispatch_root_queue_drain
方法源码dispatch_sync
源码_dispatch_sync_f
源码dispatch_barrier_sync
源码以下:_dispatch_sync_f_slow
方法中处理的__DISPATCH_WAIT_FOR_QUEUE__
方法_dq_state_drain_locked_by
方法源码dispatch_once
查看源码_dispatch_Block_invoke
就是一个宏#define _dispatch_Block_invoke(bb) \ ((dispatch_function_t)((struct Block_layout *)bb)->invoke)
就是invoke方法dispatch_semaphore_create
建立信号量,指定最大并发数dispatch_semaphore_signal
发送信号dispatch_semaphore_wait
等待信号- (void)viewDidLoad {
[super viewDidLoad];
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_semaphore_t sem = dispatch_semaphore_create(2);
//任务1
dispatch_async(queue, ^{
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
NSLog(@"执行任务1");
sleep(1);
NSLog(@"任务1完成");
dispatch_semaphore_signal(sem);
});
//任务2
dispatch_async(queue, ^{
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
NSLog(@"执行任务2");
sleep(1);
NSLog(@"任务2完成");
dispatch_semaphore_signal(sem);
});
//任务3
dispatch_async(queue, ^{
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
NSLog(@"执行任务3");
sleep(1);
NSLog(@"任务3完成");
dispatch_semaphore_signal(sem);
});
}
复制代码
打印结果以下:dispatch_semaphore_create
dispatch_semaphore_t
结构体 dispatch_semaphore_wait
os_atomic_dec2o
是个宏,由于里面是一个一个宏嵌套,因此这里一个一个剖析后以下; os_atomic_dec2o(dsema, dsema_value, acquire);
os_atomic_sub2o(dsema, dsema_value, 1, acquire)
os_atomic_sub(&(dsema)->dsema_value, (1), acquire)
_os_atomic_c11_op(&(dsema)->dsema_value, (1), acquire, sub, -)
atomic_fetch_sub_explicit(&(dsema)->dsema_value, 1)
等价于&(dsema)->dsema_value = &(dsema)->dsema_value -1
复制代码
dispatch_semaphore_signal
dispatch_semaphore_wait
相反,主要是对并发量进行加加操做 dispatch_group_create
建立组dispatch_group_async
进组任务dispatch_group_notify
等待任务执行完成通知dispatch_group_wait
暂停当前线程(阻塞当前线程),等待指定的 group 中的任务执行完成后,才会往下继续执行dispatch_group_enter
标志着一个任务追加到 group,执行一次,至关于group 中未执行完毕任务数+1dispatch_group_leave
标志着一个任务离开了 group,执行一次,至关于 group 中未执行完毕任务数-1。dispatch_group_leave
和dispatch_group_enter
须要成对出现复制代码
打印状况: dispatch_group_wait
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_group_enter(group);
dispatch_async(queue, ^{
sleep(1);
NSLog(@"任务1执行完成");
dispatch_group_leave(group);
});
dispatch_group_enter(group);
dispatch_async(queue, ^{
NSLog(@"任务2执行完成");
dispatch_group_leave(group);
});
dispatch_async(dispatch_get_global_queue(0, 0), ^{
sleep(3);
NSLog(@"任务3执行完成");
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"任务一、2执行完成");
});
NSLog(@"任务6执行完成(主线程)");
复制代码
打印结果: dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"任务一、2执行完成");
});
dispatch_group_enter(group);
dispatch_async(queue, ^{
sleep(1);
NSLog(@"任务1执行完成");
dispatch_group_leave(group);
});
dispatch_group_enter(group);
dispatch_async(queue, ^{
NSLog(@"任务2执行完成");
dispatch_group_leave(group);
});
dispatch_async(dispatch_get_global_queue(0, 0), ^{
sleep(3);
NSLog(@"任务3执行完成");
});
NSLog(@"任务6执行完成(主线程)");
复制代码
打印结果: dispatch_group_leave
就会执行通知dispatch_group_enter
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_group_enter(group);
dispatch_async(queue, ^{
sleep(1);
NSLog(@"任务1执行完成");
dispatch_group_leave(group);
});
dispatch_group_enter(group);
dispatch_async(queue, ^{
NSLog(@"任务2执行完成");
dispatch_group_leave(group);
});
dispatch_group_enter(group);
dispatch_async(dispatch_get_global_queue(0, 0), ^{
sleep(3);
NSLog(@"任务3执行完成");
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"任务一、2执行完成");
});
NSLog(@"任务6执行完成(主线程)");
复制代码
打印状况: dispatch_group_notify
一直都不会执行dispatch_group_leave
dispatch_group_leave
和dispatch_group_enter
必定要成对出现dispatch_group_create
dispatch_group_enter
dispatch_group_leave
dispatch_group_async
dispatch_group_enter
和dispatch_group_leave
两个方法的调用 dispatch_group_enter
方法 dispatch_group_leave
dispatch_group_notify
dispatch_source_merge_data
后,会执⾏ Dispatch Source
事先定义好的句柄(能够把句柄简单理解为⼀个 block )这个过程叫Custom event,⽤户事件。是dispatch source
⽀持处理的⼀种事件dispatch_source_create
建立源dispatch_source_set_event_handler
设置源事件回调dispatch_source_merge_data
源事件设置数据dispatch_source_get_data
获取源事件数据dispatch_resume
继续dispatch_suspend
挂起- (void)viewDidLoad {
[super viewDidLoad];
self.totalComplete = 0;
self.queue = dispatch_queue_create("td.com", NULL);
/*
DISPATCH_SOURCE_TYPE_DATA_ADD 自定义的事件,变量增长
DISPATCH_SOURCE_TYPE_DATA_OR 自定义的事件,变量OR
DISPATCH_SOURCE_TYPE_DATA_REPLACE 自定义的事件,变量Replace
DISPATCH_SOURCE_TYPE_MACH_SEND MACH端口发送
DISPATCH_SOURCE_TYPE_MACH_RECV MACH端口接收
DISPATCH_SOURCE_TYPE_MEMORYPRESSURE 内存报警
DISPATCH_SOURCE_TYPE_PROC 进程监听,如进程的退出、建立一个或更多的子线程、进程收到UNIX信号
DISPATCH_SOURCE_TYPE_READ IO操做,如对文件的操做、socket操做的读响应
DISPATCH_SOURCE_TYPE_SIGNAL 接收到UNIX信号时响应
DISPATCH_SOURCE_TYPE_TIMER 定时器
DISPATCH_SOURCE_TYPE_VNODE 文件状态监听,文件被删除、移动、重命名
DISPATCH_SOURCE_TYPE_WRITE IO操做,如对文件的操做、socket操做的写响应
DISPATCH_MACH_SEND_DEAD
*/
self.source = dispatch_source_create(DISPATCH_SOURCE_TYPE_DATA_ADD, 0, 0, dispatch_get_main_queue());
dispatch_source_set_event_handler(self.source, ^{
NSLog(@"%@",[NSThread currentThread]);
NSUInteger value = dispatch_source_get_data(self.source);
self.totalComplete += value;
NSLog(@"进度: %.2f",self.totalComplete/100.0);
self.progressView.progress = self.totalComplete/100.0;
});
self.isRunning = YES;
dispatch_resume(self.source);
}
- (IBAction)didClickStartOrPauseAction:(id)sender {
if (self.isRunning) {
dispatch_suspend(self.source);
dispatch_suspend(self.queue);
NSLog(@"已经暂停");
self.isRunning = NO;
[sender setTitle:@"暂停中.." forState:UIControlStateNormal];
}else{
dispatch_resume(self.source);
dispatch_resume(self.queue);
NSLog(@"已经执行了");
self.isRunning = YES;
[sender setTitle:@"暂停中.." forState:UIControlStateNormal];
}
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
NSLog(@"开始了");
for (int i= 0; i<100; i++) {
dispatch_async(self.queue, ^{
if (!self.isRunning) {
NSLog(@"已经暂停");
return;
}
sleep(1);
dispatch_source_merge_data(self.source, 1);
});
}
}
复制代码