CFRunLoopObserver 參考(CFRunLoopObserver的API)

一個(gè)CFRunLoopObserver可以提供一個(gè)回調(diào)函數(shù),使這個(gè)函數(shù)能在Runloop中運(yùn)行。對(duì)比CFRunLoopSource,當(dāng)Runloop中發(fā)生某些事時(shí)(如,sources觸發(fā),runloop進(jìn)入睡眠),CFRunLoopObserver就會(huì)被調(diào)用。 CFRunLoopObserver可以在Runloop中一次或在循環(huán)調(diào)用。

一個(gè)CFRunLoopObserver僅可以注冊(cè)在Runloop中一次,但它可以注冊(cè)在多個(gè)Runloop Mode中。

函數(shù)


CFRunLoopObserverCreateWithHandler

創(chuàng)建一個(gè)基于block回調(diào)的CFRunLoopObserver。

函數(shù)聲明:

CFRunLoopObserverRef??CFRunLoopObserverCreateWithHandler(CFAllocatorRef?allocator,CFOptionFlags?activities,Boolean repeats,CFIndex?order,void(^block)(CFRunLoopObserverRef?observer,CFRunLoopActivity?activity));

參數(shù):

allocator:這個(gè)參數(shù)用來(lái)分配空間給新的對(duì)象。默認(rèn)情況下使用NULL或者kCFAllocatorDefault

activities:設(shè)置Runloop的運(yùn)行階段的標(biāo)志,當(dāng)運(yùn)行到此階段時(shí),CFRunLoopObserver會(huì)被調(diào)用。具體可看Run Loop Activities。activities其實(shí)是一個(gè)枚舉,這里把它的枚舉類(lèi)型展示出來(lái):

enum ?CFRunLoopActivity{

? ? ?kCFRunLoopEntry=(1<<0),

? ? ?kCFRunLoopBeforeTimers=(1<<1),

? ? ?kCFRunLoopBeforeSources=(1<<2),

? ? ?kCFRunLoopBeforeWaiting=(1<<5),

? ? ?kCFRunLoopAfterWaiting=(1<<6),

? ? ?kCFRunLoopExit=(1<<7),

? ? ?kCFRunLoopAllActivities=0x0FFFFFFFU

? };

typedef ?enumCFRunLoopActivityCFRunLoopActivity;

repeats:CFRunLoopObserver是否循環(huán)調(diào)用,false為單詞調(diào)用,否則循環(huán)調(diào)用。

order:CFRunLoopObserver的優(yōu)先級(jí),當(dāng)在Runloop同一運(yùn)行階段中有多個(gè)CFRunLoopObserver時(shí),根據(jù)這個(gè)來(lái)先后調(diào)用CFRunLoopObserver。正常情況下使用0。

block:回調(diào)的block。

這個(gè)block有兩個(gè)參數(shù):

observer:正在運(yùn)行的run loop observe。

activity:runloop當(dāng)前的運(yùn)行階段。

返回值:

新的CFRunLoopObserver對(duì)象。

詳情:

這個(gè)CFRunLoopObserver不能自動(dòng)添加進(jìn)Runloop中,需使用CFRunLoopAddObserver。

有效:

OS X v10.7及其以后。


個(gè)人解釋一下這個(gè)函數(shù),順便觀察CFRunLoopObserver在Runloop中怎么被調(diào)用的。

CFRunLoopObserver在Runloop的調(diào)用:

1.我們首先在Runloop的源代碼中找到

static int32_t ?__CFRunLoopRun(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFTimeInterval seconds, Boolean stopAfterHandle,CFRunLoopModeRef previousMode)

這是Runloo的主循環(huán)函數(shù),Runloop都在這里面運(yùn)行。

然后在這個(gè)函數(shù)里面找到對(duì)CFRunLoopObserver調(diào)用函數(shù):

if(rlm->_observerMask&kCFRunLoopBeforeTimers)__CFRunLoopDoObservers(rl, rlm,kCFRunLoopBeforeTimers);

if(rlm->_observerMask&kCFRunLoopBeforeSources)__CFRunLoopDoObservers(rl, rlm,kCFRunLoopBeforeSources);

我們可以看到從這里進(jìn)去可以看到CFRunLoopObserver的回調(diào)函數(shù)是怎么被調(diào)用的。


我們可以從中看到里面調(diào)用了

__CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__(rlo->_callout, rlo, activity, rlo->_context.info);

再進(jìn)去可以看到


從中可以看到里面調(diào)用了回調(diào)函數(shù),而且這個(gè)回調(diào)函數(shù)的形參是確定的(下面有講這個(gè)回調(diào)函數(shù))?;蛟S我們會(huì)疑惑,這里我們并沒(méi)有回調(diào)block,怎么有block的回調(diào)?那這里我們就要看CFRunLoopObserverCreateWithHandler這個(gè)函數(shù)的源碼了:


我們從中可以看到,這個(gè)函數(shù)內(nèi)部本身還是調(diào)用了CFRunLoopObserverCreate(下面會(huì)講)這個(gè)函數(shù),但它對(duì)回調(diào)函數(shù)進(jìn)行處理(也就是圖中的_runLoopObserverWithBlockContext函數(shù)),使block回調(diào)隱藏在回調(diào)函數(shù)內(nèi)。


CFRunLoopObserverCreate

創(chuàng)建一個(gè)基于回調(diào)函數(shù)的CFRunLoopObserver。

函數(shù)聲明:

CFRunLoopObserverRef?CFRunLoopObserverCreate(CFAllocatorRef?allocator,CFOptionFlags?activities,Boolean repeats,CFIndex?order,CFRunLoopObserverCallBack?callout,CFRunLoopObserverContext?*context);

相同的參數(shù)可以參考上一個(gè)API函數(shù)的聲明,這里只說(shuō)不一樣的。

context:CFRunLoopObserver結(jié)構(gòu)體里面的一個(gè)結(jié)構(gòu)體,它主要使用來(lái)傳遞消息的,在回調(diào)函數(shù)外面代碼生成的信息可以傳進(jìn)回調(diào)函數(shù)內(nèi)進(jìn)行使用,形成了一個(gè)消息傳遞。在應(yīng)用中,context應(yīng)該是下面那樣的:

CFRunLoopObserverContext ? ?observerContext = {

? ? ? ? ? ? ? ? ? 0,

? ? ? ? ? ? ? ? ?info, //這里填寫(xiě)你要傳遞的信息。

? ? ? ? ? ? ? ? ? &CFRetain,

? ? ? ? ? ? ? ? ? &CFRelease,

? ? ? ? ? ? ? ? ? ?NULL

};

這里不進(jìn)行源碼講解了,沒(méi)什么好講的,源碼的內(nèi)容也是根據(jù)上面的形參對(duì)CFRunLoopObserver的結(jié)構(gòu)體進(jìn)行賦值。


CFRunLoopObserverDoesRepeat

返回一個(gè)布爾值來(lái)查看所檢測(cè)的CFRunLoopObserver是否循環(huán)調(diào)用。

函數(shù)聲明:

BooleanCFRunLoopObserverDoesRepeat(CFRunLoopObserverRef?observer);

嗯。自行體會(huì)吧,沒(méi)什么好說(shuō)的。


CFRunLoopObserverGetActivities

返回所檢測(cè)的CFRunLoopObserver的被運(yùn)行時(shí)的Runloop的運(yùn)行階段。

函數(shù)聲明:

CFOptionFlags?CFRunLoopObserverGetActivities(CFRunLoopObserverRef?observer);


下面的幾個(gè)函數(shù)都是檢測(cè)的CFRunLoopObserver的,沒(méi)啥可說(shuō)的:

CFRunLoopObserverGetContext

CFRunLoopObserverGetOrder

CFRunLoopObserverGetTypeID



CFRunLoopObserverInvalidate

作廢一個(gè)在運(yùn)行的CFRunLoopObserver。

函數(shù)聲明:

void CFRunLoopObserverInvalidate(CFRunLoopObserverRef?observer);



CFRunLoopObserverIsValid

檢測(cè)一個(gè)CFRunLoopObserver是否還有效。

函數(shù)聲明:

Boolean CFRunLoopObserverIsValid(CFRunLoopObserverRef?observer);



CFRunLoopAddObserver

添加一個(gè)CFRunLoopObserver到一個(gè)run loop mode中。

函數(shù)聲明:

void CFRunLoopAddObserver(CFRunLoopRef?rl,CFRunLoopObserverRef?observer,CFStringRef?mode);

形參:

mode:是一個(gè)字符串,代表Runloop 中的一個(gè)mode,這里展示兩個(gè)常用mode的字符串:

CF_EXPORT const CFStringRef kCFRunLoopDefaultMode;

CF_EXPORT const CFStringRef kCFRunLoopCommonModes;

注意:在添加CFRunLoopObserver后(即這個(gè)函數(shù)后),要用CFRelease函數(shù)釋放掉CFRunLoopObserver。

CFRunLoopContainsObserver

檢測(cè)一個(gè)run loop mode是否含有CFRunLoopObserver。

函數(shù)聲明:

Boolean CFRunLoopContainsObserver(CFRunLoopRef?rl,?CFRunLoopObserverRef?observer,?CFStringRef?mode);



CFRunLoopRemoveObserver

將一個(gè)CFRunLoopObserver從一個(gè)run loop mode中移除。

void CFRunLoopRemoveObserver(CFRunLoopRef?rl,?CFRunLoopObserverRef?observer,?CFStringRef?mode);




回調(diào)函數(shù)


CFRunLoopObserverCallBack

回調(diào)函數(shù)形式:

typedef void (*CFRunLoopObserverCallBack) (CFRunLoopObserverRef?observer,CFRunLoopActivity?activity,void *info);

形參:

只講info。從上面的源碼可以看出,這個(gè)info是CFRunLoopObserverContext結(jié)構(gòu)體的一個(gè)成員元素,用來(lái)傳遞消息。



數(shù)據(jù)類(lèi)型

兩種:

CFRunLoopObserverContext

CFRunLoopObserverRef

簡(jiǎn)述它們的關(guān)系:

CFRunLoopObserverRef中含有回調(diào)函數(shù),CFRunLoopObserverContext之類(lèi)的。

CFRunLoopObserverContext含有info,用來(lái)消息傳遞,還包含一些操作函數(shù)。

最后編輯于
?著作權(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ù)。

相關(guān)閱讀更多精彩內(nèi)容

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