dispatch object.h

版本:iOS13.5

object.h

dispatch其他文件通道

索引

  • 增加調(diào)度對(duì)象object的引用計(jì)數(shù)
    dispatch_retain
  • 減少調(diào)度對(duì)象object的引用計(jì)數(shù)
    dispatch_release
  • 為調(diào)試對(duì)象object綁定一個(gè)參數(shù)指針context
    dispatch_set_context
  • 獲取調(diào)試對(duì)象object綁定的參數(shù)指針
    dispatch_get_context
  • 為調(diào)度對(duì)象object設(shè)置終結(jié)函數(shù)
    dispatch_set_finalizer_f
  • 激活調(diào)度對(duì)象object
    dispatch_activate
  • 掛起調(diào)度對(duì)象object
    dispatch_suspend
  • 恢復(fù)已經(jīng)掛起的調(diào)度對(duì)象object
    dispatch_resume
  • 為調(diào)度對(duì)象object設(shè)置qos_class
    dispatch_set_qos_class_floor
  • 同步等待對(duì)象object或超時(shí)
    dispatch_wait
  • 對(duì)象object全部執(zhí)行后,將notification_block提交給隊(duì)列queue再執(zhí)行。
    dispatch_notify
  • 取消對(duì)象object
    dispatch_cancel
  • 測(cè)試對(duì)象object是否已被取消
    dispatch_testcancel

詳解

  • 增加調(diào)度對(duì)象object的引用計(jì)數(shù)
void dispatch_retain(dispatch_object_t object);

引用計(jì)數(shù)大于0時(shí)不會(huì)被釋放,只能在非ARC模式下使用。
必須和dispatch_release成對(duì)使用
object 調(diào)試對(duì)象 dispatch_queue_tdispatch_source_t都可以當(dāng)做dispatch_object_t使用

  • 減少調(diào)度對(duì)象object的引用計(jì)數(shù)
void dispatch_release(dispatch_object_t object);

一旦引用計(jì)數(shù)為0后,系統(tǒng)會(huì)異步釋放該對(duì)象

例:
    dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_CONCURRENT);
    dispatch_retain(queue);
    dispatch_release(queue);
  • 為調(diào)試對(duì)象object綁定一個(gè)參數(shù)指針context
void dispatch_set_context(dispatch_object_t object, void *_Nullable context);

context 為一個(gè)指針 void *類(lèi)型 可以為NULL
該參數(shù)指針在dispatch_set_finalizer_f的finalizer調(diào)用時(shí)使用

  • 獲取調(diào)試對(duì)象object綁定的參數(shù)指針
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
  • 為調(diào)度對(duì)象object設(shè)置終結(jié)函數(shù)
void dispatch_set_finalizer_f(dispatch_object_t object, 
              dispatch_function_t _Nullable finalizer);

終結(jié)函數(shù)是當(dāng)object被釋放時(shí)調(diào)用的函數(shù)
finalizer 終結(jié)函數(shù)的指針typedef void (*dispatch_function_t)(void *_Nullable);
此時(shí)finalizer所需的void *參數(shù)由dispatch_set_context方法來(lái)設(shè)置
可以在終結(jié)函數(shù)中釋放與object關(guān)聯(lián)的任何資源

例:
    dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_CONCURRENT);
    int context = 10;
    dispatch_set_context(queue, &context);    
    NSLog(@"11");
    //在queue上添加了一個(gè)dispatch_after函數(shù) 此時(shí)queue不會(huì)釋放 待after函數(shù)執(zhí)行完后queue釋放 然后觸發(fā)終結(jié)函數(shù)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
  • 激活調(diào)度對(duì)象object
void dispatch_activate(dispatch_object_t object);

調(diào)度對(duì)象(例如queue和source)可以在非活動(dòng)狀態(tài)下創(chuàng)建。必須先激活這種狀態(tài)的對(duì)象,然后才能調(diào)用與它們關(guān)聯(lián)的任何block。
在活動(dòng)對(duì)象上調(diào)用dispatch_activate是無(wú)效的
可以使用dispatch_set_target_queue更改非活動(dòng)對(duì)象的目標(biāo)隊(duì)列。一旦最初不活動(dòng)的對(duì)象被激活,就不再允許更改目標(biāo)隊(duì)列。

  • 掛起調(diào)度對(duì)象object
void dispatch_suspend(dispatch_object_t object);

掛起的對(duì)象object將不會(huì)調(diào)用與其關(guān)聯(lián)的任何block。已經(jīng)運(yùn)行的block不會(huì)停止,并且在已經(jīng)運(yùn)行的block完成之后,才會(huì)掛起該對(duì)象object。
dispatch_suspend必須和dispatch_resume成對(duì)使用

  • 恢復(fù)已經(jīng)掛起的調(diào)度對(duì)象object
void dispatch_resume(dispatch_object_t object);

對(duì)處于非活動(dòng)狀態(tài)且未掛起的dispatch_source_t對(duì)象調(diào)用dispatch_resume與調(diào)用dispatch_activate具有相同的效果。對(duì)于新代碼,首選使用dispatch_activate

例:
    dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_CONCURRENT);
    
    //在主隊(duì)列中1秒后將queue掛起
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        NSLog(@"開(kāi)始掛起");
        dispatch_suspend(queue);
    });
    //因?yàn)閝ueue已被掛起 雖然2秒已到 但block不會(huì)執(zhí)行
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), queue, ^{
        NSLog(@"2秒時(shí)的操作");
    });
    //在主隊(duì)列中3秒后將queue恢復(fù) 因?yàn)?秒的操作時(shí)間已到,待queue一恢復(fù) ,就會(huì)直接執(zhí)行block
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        NSLog(@"開(kāi)始恢復(fù)");
        dispatch_resume(queue);
    });
輸出:
開(kāi)始掛起
開(kāi)始恢復(fù)
2秒時(shí)的操作
  • 為調(diào)度對(duì)象object設(shè)置qos_class
void dispatch_set_qos_class_floor(dispatch_object_t object,
        dispatch_qos_class_t qos_class, int relative_priority);

object 調(diào)度對(duì)象 類(lèi)型可為dispatch_queue_tdispatch_workloop_tdispatch_source_t
對(duì)象必須是非活躍的
qos_class 優(yōu)先級(jí)從上住下依次變低

__QOS_ENUM(qos_class, unsigned int,
    //該線程執(zhí)行的工作的QOS類(lèi)會(huì)與用戶交互。
    //此類(lèi)工作相對(duì)于系統(tǒng)上的其他工作具有更高的優(yōu)先級(jí)
    //這不是用于大型任務(wù)的高能效QOS類(lèi)。
    //此QOS類(lèi)的使用應(yīng)限于與用戶的關(guān)鍵交互,例如處理主事件循環(huán)上的事件,視圖繪制,動(dòng)畫(huà)等
    QOS_CLASS_USER_INTERACTIVE = 0x21,
    //該線程執(zhí)行的工作的QOS類(lèi)由用戶啟動(dòng),并且用戶可能正在等待結(jié)果
    QOS_CLASS_USER_INITIATED = 0x19,
    //默認(rèn)
    QOS_CLASS_DEFAULT = 0x15,
    //該線程執(zhí)行的工作的QOS類(lèi)可能由用戶啟動(dòng)也可能未啟動(dòng),并且用戶不太可能立即等待結(jié)果
    QOS_CLASS_UTILITY = 0x11,
    //指示該線程執(zhí)行的工作的QOS類(lèi)不是由用戶啟動(dòng)的,并且用戶可能不知道結(jié)果
    QOS_CLASS_BACKGROUND = 0x09,
    //未指定
    QOS_CLASS_UNSPECIFIED = 0x00,
);

relative_priority QOS類(lèi)中的相對(duì)優(yōu)先級(jí)。該值是與最大支持的調(diào)度程序優(yōu)先級(jí)的負(fù)偏移量。傳遞大于0或小于QOS_MIN_RELATIVE_PRIORITY的值將導(dǎo)致返回NULL。
#define QOS_MIN_RELATIVE_PRIORITY (-15)

  • 同步等待對(duì)象object或超時(shí)
long dispatch_wait(void *object, dispatch_time_t timeout);

object 對(duì)象
若對(duì)象為dispatch_block_t則調(diào)用dispatch_block_wait
若對(duì)象為dispatch_group_t則調(diào)用dispatch_group_wait
若對(duì)象為dispatch_semaphore_t則調(diào)用dispatch_semaphore_wait
timeout 超時(shí)時(shí)間 可為DISPATCH_TIME_FOREVERDISPATCH_TIME_NOW或通過(guò)dispatch_time創(chuàng)建

例:
    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);
        //兩種寫(xiě)法效果一致
//        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
  • 對(duì)象object全部執(zhí)行后,將notification_block提交給隊(duì)列queue再執(zhí)行。
void dispatch_notify(void *object, dispatch_object_t queue,
        dispatch_block_t notification_block);

object 對(duì)象
若對(duì)象為dispatch_block_t則調(diào)用dispatch_block_notify
若對(duì)象為dispatch_group_t則調(diào)用dispatch_group_notify
queue 要執(zhí)行notification_block的隊(duì)列

  • 取消對(duì)象object
void dispatch_cancel(void *object);

object 對(duì)象
若對(duì)象為dispatch_block_t則調(diào)用dispatch_block_cancel
若對(duì)象為dispatch_source_t則調(diào)用dispatch_source_cancel

  • 測(cè)試對(duì)象object是否已被取消
long dispatch_testcancel(void *object);

object 對(duì)象
若對(duì)象為dispatch_block_t則調(diào)用dispatch_block_testcancel
若對(duì)象為dispatch_source_t則調(diào)用dispatch_source_testcancel

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容