RAC(ReactiveCocoa)介紹(六)——RACScheduler

上一篇介紹了一下RAC訂閱信號(hào)中晴音,方法實(shí)現(xiàn)RACCompoundDisposable真正的訂閱者類的相關(guān)介紹灰粮。
這一篇炬搭,將在訂閱信號(hào)的方法中繼續(xù)探究夺姑,當(dāng)真正的訂閱者初始化之后墩邀,后續(xù)代碼涉及到了RACScheduler類的使用。將針對(duì)RACScheduler類進(jìn)行深入的剖析盏浙。


RACScheduler類的使用

先從上圖的代碼中可以發(fā)現(xiàn)眉睹,RACScheduler的block代碼塊中,有執(zhí)行self.didSubscribe( )代碼塊的代碼废膘,即執(zhí)行創(chuàng)建信號(hào)時(shí)的代碼塊竹海,也就意味著此處的schedule代碼塊是必須執(zhí)行。
跳轉(zhuǎn)進(jìn)入查看schedule方法殖卑,可以發(fā)現(xiàn)有多個(gè)基于RACScheduler的子類站削,都有該實(shí)現(xiàn)方法坊萝。
在RACScheduler類中孵稽,有三種子類:RACImmediateScheduler、RACSubscriptionScheduler和RACQueueScheduler


schedule方法跳轉(zhuǎn)列表

在RACImmediateScheduler子類看到schedule方法中十偶,是立即執(zhí)行block代碼塊菩鲜。
- (RACDisposable *)schedule:(void (^)(void))block {
    NSCParameterAssert(block != NULL);

    block();
    return nil;
}

接著是RACSubscriptionScheduler子類中的schedule方法實(shí)現(xiàn)。

- (RACDisposable *)schedule:(void (^)(void))block {
    NSCParameterAssert(block != NULL);

    if (RACScheduler.currentScheduler == nil) return [self.backgroundScheduler schedule:block];

    block();
    return nil;
}

在RACSubscriptionScheduler子類schedule方法中惦积,在執(zhí)行代碼塊之前接校,會(huì)先判斷當(dāng)前線程、當(dāng)前隊(duì)列是否為nil狮崩。若不為nil蛛勉,則會(huì)在后臺(tái)開啟一個(gè)串行異步線程隊(duì)列。而self.backgroundScheduler通過[RACScheduler scheduler]創(chuàng)建并實(shí)例化的睦柴,最終可以追溯到以下代碼中:

+ (RACScheduler *)schedulerWithPriority:(RACSchedulerPriority)priority name:(NSString *)name {
    return [[RACTargetQueueScheduler alloc] initWithName:name targetQueue:dispatch_get_global_queue(priority, 0)];
}

上述代碼意味著是由RACTargetQueueScheduler類初始化诽凌,而RACTargetQueueScheduler是RACQueueScheduler的子類。
而RACTargetQueueScheduler類實(shí)例化方法實(shí)現(xiàn)中坦敌,使用GCD在目標(biāo)線程里創(chuàng)建了一個(gè)串行隊(duì)列侣诵。


RACTargetQueueScheduler類實(shí)例化方法實(shí)現(xiàn)

那么,此時(shí)來看下RACQueueScheduler類的schedule方法實(shí)現(xiàn):

- (RACDisposable *)schedule:(void (^)(void))block {
    NSCParameterAssert(block != NULL);

    RACDisposable *disposable = [[RACDisposable alloc] init];

    dispatch_async(self.queue, ^{
        if (disposable.disposed) return;
        [self performAsCurrentScheduler:block];
    });

    return disposable;
}

此處使用GCD開啟了一個(gè)異步線程狱窘,在后臺(tái)執(zhí)行下一步操作杜顺,作為當(dāng)前的Scheduler去執(zhí)行。所以說蘸炸,RACQueueScheduler類實(shí)現(xiàn)的schedule方法是在后臺(tái)創(chuàng)建一個(gè)串行隊(duì)列異步線程來實(shí)現(xiàn)最終的代碼塊執(zhí)行躬络。


performAsCurrentScheduler方法實(shí)現(xiàn)

在該方法中,首先找到當(dāng)前的Scheduler隊(duì)列搭儒;然后從當(dāng)前線程字典中找到關(guān)于RACSchedulerCurrentSchedulerKey鍵值并將RACScheduler自己賦值給它穷当。
如果當(dāng)前Scheduler隊(duì)列不為空越锈,則會(huì)把當(dāng)前的Scheduler隊(duì)列存入到當(dāng)前線程字典的RACSchedulerCurrentSchedulerKey鍵值中;若為空膘滨,則把當(dāng)前線程字典的RACSchedulerCurrentSchedulerKey鍵值內(nèi)容全部刪除甘凭。一旦刪除,意味著當(dāng)前線程中的隊(duì)列已不存在火邓。當(dāng)隊(duì)列不存在時(shí)丹弱,會(huì)利用Objective-C的動(dòng)態(tài)機(jī)制,會(huì)自動(dòng)修復(fù)重啟當(dāng)前的隊(duì)列铲咨。
上面有一段代碼:

    @autoreleasepool {
        block();
    }

此段代碼中的block執(zhí)行時(shí)躲胳,也就是創(chuàng)建RACSignal信號(hào)的block中,會(huì)有臨時(shí)變量的產(chǎn)生纤勒,autoreleasepool意味著延遲釋放坯苹。其中涉及到runloop知識(shí)范圍,此處不做深入討論摇天。

以上內(nèi)容主要講解了RACScheduler類以及三種子類的作用與實(shí)現(xiàn)過程原理粹湃,后續(xù)會(huì)繼續(xù)探究RAC內(nèi)部實(shí)現(xiàn)的具體流程。


該文章首次發(fā)表在 簡(jiǎn)書:我只不過是出來寫寫代碼 博客泉坐,并自動(dòng)同步至 騰訊云:我只不過是出來寫寫iOS 博客

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末为鳄,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子腕让,更是在濱河造成了極大的恐慌孤钦,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,589評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件纯丸,死亡現(xiàn)場(chǎng)離奇詭異偏形,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)觉鼻,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,615評(píng)論 3 396
  • 文/潘曉璐 我一進(jìn)店門俊扭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人滑凉,你說我怎么就攤上這事统扳。” “怎么了畅姊?”我有些...
    開封第一講書人閱讀 165,933評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵咒钟,是天一觀的道長。 經(jīng)常有香客問我若未,道長朱嘴,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,976評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮萍嬉,結(jié)果婚禮上乌昔,老公的妹妹穿的比我還像新娘。我一直安慰自己壤追,他們只是感情好磕道,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,999評(píng)論 6 393
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著行冰,像睡著了一般溺蕉。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上悼做,一...
    開封第一講書人閱讀 51,775評(píng)論 1 307
  • 那天疯特,我揣著相機(jī)與錄音,去河邊找鬼肛走。 笑死漓雅,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的朽色。 我是一名探鬼主播邻吞,決...
    沈念sama閱讀 40,474評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼纵搁!你這毒婦竟也來了吃衅?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,359評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤腾誉,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后峻呕,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體利职,經(jīng)...
    沈念sama閱讀 45,854評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,007評(píng)論 3 338
  • 正文 我和宋清朗相戀三年瘦癌,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了猪贪。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,146評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡讯私,死狀恐怖热押,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情斤寇,我是刑警寧澤桶癣,帶...
    沈念sama閱讀 35,826評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站娘锁,受9級(jí)特大地震影響牙寞,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,484評(píng)論 3 331
  • 文/蒙蒙 一间雀、第九天 我趴在偏房一處隱蔽的房頂上張望悔详。 院中可真熱鬧,春花似錦惹挟、人聲如沸茄螃。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,029評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽责蝠。三九已至,卻和暖如春萎庭,著一層夾襖步出監(jiān)牢的瞬間霜医,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,153評(píng)論 1 272
  • 我被黑心中介騙來泰國打工驳规, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留肴敛,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,420評(píng)論 3 373
  • 正文 我出身青樓吗购,卻偏偏與公主長得像医男,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子捻勉,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,107評(píng)論 2 356