版本:iOS13.5
object.h
索引
- 增加调度对象object的引用计数
dispatch_retain
- 减少调度对象object的引用计数
dispatch_release
- 为调试对象object绑定一个参数指针context
dispatch_set_context
- 获取调试对象object绑定的参数指针
dispatch_get_context
- 为调度对象object设置终结函数
dispatch_set_finalizer_f
- 激活调度对象object
dispatch_activate
- 挂起调度对象object
dispatch_suspend
- 恢复已经挂起的调度对象object
dispatch_resume
- 为调度对象object设置qos_class
dispatch_set_qos_class_floor
- 同步等待对象object或超时
dispatch_wait
- 对象object全部执行后,将notification_block提交给队列queue再执行。
dispatch_notify
- 取消对象object
dispatch_cancel
- 测试对象object是否已被取消
dispatch_testcancel
详解
- 增加调度对象object的引用计数
void dispatch_retain(dispatch_object_t object);
引用计数大于0时不会被释放,只能在非ARC模式下使用。
必须和dispatch_release
成对使用
object 调试对象 dispatch_queue_t
和dispatch_source_t
都可以当做dispatch_object_t
使用
- 减少调度对象object的引用计数
void dispatch_release(dispatch_object_t object);
一旦引用计数为0后,系统会异步释放该对象
例:
dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_CONCURRENT);
dispatch_retain(queue);
dispatch_release(queue);
- 为调试对象object绑定一个参数指针context
void dispatch_set_context(dispatch_object_t object, void *_Nullable context);
context 为一个指针 void *
类型 可以为NULL
该参数指针在dispatch_set_finalizer_f
的finalizer调用时使用
- 获取调试对象object绑定的参数指针
void *_Nullable dispatch_get_context(dispatch_object_t object);
例:
dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_CONCURRENT);
int context = 10;
dispatch_set_context(queue, &context);
int *adress = dispatch_get_context(queue);
NSLog(@"%d", *adress);
输出:
10
- 为调度对象object设置终结函数
void dispatch_set_finalizer_f(dispatch_object_t object,
dispatch_function_t _Nullable finalizer);
终结函数是当object被释放时调用的函数
finalizer 终结函数的指针typedef void (*dispatch_function_t)(void *_Nullable);
此时finalizer所需的void *
参数由dispatch_set_context
方法来设置
可以在终结函数中释放与object关联的任何资源
例:
dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_CONCURRENT);
int context = 10;
dispatch_set_context(queue, &context);
NSLog(@"11");
//在queue上添加了一个dispatch_after函数 此时queue不会释放 待after函数执行完后queue释放 然后触发终结函数finalizer
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), queue, ^{
NSLog(@"22");
});
dispatch_set_finalizer_f(queue, finalizer);
void finalizer(void *context) {
NSLog(@"33");
}
输出:
11
22
33
- 激活调度对象object
void dispatch_activate(dispatch_object_t object);
调度对象(例如queue和source)可以在非活动状态下创建。必须先激活这种状态的对象,然后才能调用与它们关联的任何block。
在活动对象上调用dispatch_activate
是无效的
可以使用dispatch_set_target_queue
更改非活动对象的目标队列。一旦最初不活动的对象被激活,就不再允许更改目标队列。
- 挂起调度对象object
void dispatch_suspend(dispatch_object_t object);
挂起的对象object将不会调用与其关联的任何block。已经运行的block不会停止,并且在已经运行的block完成之后,才会挂起该对象object。
dispatch_suspend
必须和dispatch_resume
成对使用
- 恢复已经挂起的调度对象object
void dispatch_resume(dispatch_object_t object);
对处于非活动状态且未挂起的dispatch_source_t
对象调用dispatch_resume
与调用dispatch_activate
具有相同的效果。对于新代码,首选使用dispatch_activate
例:
dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_CONCURRENT);
//在主队列中1秒后将queue挂起
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"开始挂起");
dispatch_suspend(queue);
});
//因为queue已被挂起 虽然2秒已到 但block不会执行
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), queue, ^{
NSLog(@"2秒时的操作");
});
//在主队列中3秒后将queue恢复 因为2秒的操作时间已到,待queue一恢复 ,就会直接执行block
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"开始恢复");
dispatch_resume(queue);
});
输出:
开始挂起
开始恢复
2秒时的操作
- 为调度对象object设置qos_class
void dispatch_set_qos_class_floor(dispatch_object_t object,
dispatch_qos_class_t qos_class, int relative_priority);
object 调度对象 类型可为dispatch_queue_t
和dispatch_workloop_t
和dispatch_source_t
对象必须是非活跃的
qos_class 优先级从上住下依次变低
__QOS_ENUM(qos_class, unsigned int,
//该线程执行的工作的QOS类会与用户交互。
//此类工作相对于系统上的其他工作具有更高的优先级
//这不是用于大型任务的高能效QOS类。
//此QOS类的使用应限于与用户的关键交互,例如处理主事件循环上的事件,视图绘制,动画等
QOS_CLASS_USER_INTERACTIVE = 0x21,
//该线程执行的工作的QOS类由用户启动,并且用户可能正在等待结果
QOS_CLASS_USER_INITIATED = 0x19,
//默认
QOS_CLASS_DEFAULT = 0x15,
//该线程执行的工作的QOS类可能由用户启动也可能未启动,并且用户不太可能立即等待结果
QOS_CLASS_UTILITY = 0x11,
//指示该线程执行的工作的QOS类不是由用户启动的,并且用户可能不知道结果
QOS_CLASS_BACKGROUND = 0x09,
//未指定
QOS_CLASS_UNSPECIFIED = 0x00,
);
relative_priority QOS类中的相对优先级。该值是与最大支持的调度程序优先级的负偏移量。传递大于0或小于QOS_MIN_RELATIVE_PRIORITY
的值将导致返回NULL。
#define QOS_MIN_RELATIVE_PRIORITY (-15)
- 同步等待对象object或超时
long dispatch_wait(void *object, dispatch_time_t timeout);
object 对象
若对象为dispatch_block_t
则调用dispatch_block_wait
若对象为dispatch_group_t
则调用dispatch_group_wait
若对象为dispatch_semaphore_t
则调用dispatch_semaphore_wait
timeout 超时时间 可为DISPATCH_TIME_FOREVER
、DISPATCH_TIME_NOW
或通过dispatch_time
创建
例:
dispatch_semaphore_t sem = dispatch_semaphore_create(0);
dispatch_async(dispatch_queue_create("sem", DISPATCH_QUEUE_CONCURRENT), ^{
NSLog(@"1");
dispatch_wait(sem, DISPATCH_TIME_FOREVER);
//两种写法效果一致
// dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
NSLog(@"3");
});
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"2");
dispatch_semaphore_signal(sem);
});
输出:
17:19:01.336476+0800 DEMO[82832:8357215] 1
17:19:04.336522+0800 DEMO[82832:8356709] 2
17:19:04.336713+0800 DEMO[82832:8357215] 3
- 对象object全部执行后,将notification_block提交给队列queue再执行。
void dispatch_notify(void *object, dispatch_object_t queue,
dispatch_block_t notification_block);
object 对象
若对象为dispatch_block_t
则调用dispatch_block_notify
若对象为dispatch_group_t
则调用dispatch_group_notify
queue 要执行notification_block的队列
- 取消对象object
void dispatch_cancel(void *object);
object 对象
若对象为dispatch_block_t
则调用dispatch_block_cancel
若对象为dispatch_source_t
则调用dispatch_source_cancel
- 测试对象object是否已被取消
long dispatch_testcancel(void *object);
object 对象
若对象为dispatch_block_t
则调用dispatch_block_testcancel
若对象为dispatch_source_t
则调用dispatch_source_testcancel