美文网首页
dispatch object.h

dispatch object.h

作者: 想聽丿伱說衹愛我 | 来源:发表于2020-07-24 17:28 被阅读0次

版本:iOS13.5

object.h

dispatch其他文件通道

索引

  • 增加调度对象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_tdispatch_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_tdispatch_workloop_tdispatch_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_FOREVERDISPATCH_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

相关文章

网友评论

      本文标题:dispatch object.h

      本文链接:https://www.haomeiwen.com/subject/vewjlktx.html