dispatch object.h

2020-07-24  本文已影响0人  想聽丿伱說衹愛我

版本:iOS13.5

object.h

dispatch其他文件通道

索引

详解

void dispatch_retain(dispatch_object_t object);

引用计数大于0时不会被释放,只能在非ARC模式下使用。
必须和dispatch_release成对使用
object 调试对象 dispatch_queue_tdispatch_source_t都可以当做dispatch_object_t使用

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);
void dispatch_set_context(dispatch_object_t object, void *_Nullable context);

context 为一个指针 void *类型 可以为NULL
该参数指针在dispatch_set_finalizer_f的finalizer调用时使用

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
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
void dispatch_activate(dispatch_object_t object);

调度对象(例如queue和source)可以在非活动状态下创建。必须先激活这种状态的对象,然后才能调用与它们关联的任何block。
在活动对象上调用dispatch_activate是无效的
可以使用dispatch_set_target_queue更改非活动对象的目标队列。一旦最初不活动的对象被激活,就不再允许更改目标队列。

void dispatch_suspend(dispatch_object_t object);

挂起的对象object将不会调用与其关联的任何block。已经运行的block不会停止,并且在已经运行的block完成之后,才会挂起该对象object。
dispatch_suspend必须和dispatch_resume成对使用

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秒时的操作
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)

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
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的队列

void dispatch_cancel(void *object);

object 对象
若对象为dispatch_block_t则调用dispatch_block_cancel
若对象为dispatch_source_t则调用dispatch_source_cancel

long dispatch_testcancel(void *object);

object 对象
若对象为dispatch_block_t则调用dispatch_block_testcancel
若对象为dispatch_source_t则调用dispatch_source_testcancel

上一篇 下一篇

猜你喜欢

热点阅读