RAC(ReactiveCocoa)介紹(五)——RACPassthroughSubscriber

上一篇整體分析了RAC的信號(hào)流程,這樣對(duì)RAC的工作原理有了整體的認(rèn)識(shí)。
接下來(lái)將逐步深入了解RAC實(shí)現(xiàn)的底層。

RACPassthroughSubscriber類(lèi)

在上一篇文章的流程分析中,真正的訂閱者是RACPassthroughSubscriber類(lèi),它將創(chuàng)建信號(hào)、訂閱者與銷(xiāo)毀者進(jìn)行了關(guān)聯(lián)。
在RACPassthroughSubscriber類(lèi)的頭文件中,聲明了一個(gè)RACSignal類(lèi)的成員變量。

@property (nonatomic, unsafe_unretained, readonly) RACSignal *signal;

在聲明的屬性中,定義了signal為unsafe_unretained,意味著signal為弱引用,但又與weak屬性不同。weak屬性當(dāng)為nil時(shí),對(duì)象會(huì)自動(dòng)執(zhí)行釋放功能,導(dǎo)致該對(duì)象無(wú)法繼續(xù)被使用。而unsafe_unretained同樣作為弱引用,當(dāng)為nil時(shí)卻指針不會(huì)自動(dòng)釋放,保留一個(gè)野指針。如果使用此指針,程序會(huì)拋出 BAD_ACCESS 的異常。

在此處多問(wèn)一個(gè)為什么,此處信號(hào)為什么要使用unsafe_unretained而不是weak屬性修飾?
找了網(wǎng)上的幾處分析,都在說(shuō)下面這句:
這里之所以不是weak,是因?yàn)橐肦ACSignal僅僅只是一個(gè)DTrace probes動(dòng)態(tài)跟蹤技術(shù)的探針。如果設(shè)置成weak,會(huì)造成沒(méi)必要的性能損失。

個(gè)人理解:unsafe_unretained屬性不會(huì)自動(dòng)將signal變?yōu)閚il,而weak屬性會(huì)自動(dòng)置為nil。當(dāng)signal置為nil時(shí),當(dāng)前signal不再是一個(gè)信號(hào)類(lèi)型的對(duì)象,就無(wú)法再繼續(xù)執(zhí)行訂閱信號(hào)、發(fā)送信號(hào)動(dòng)作。所以要使用unsafe_unretained屬性保留當(dāng)前signal的類(lèi)型,即使變成了野指針。

_signal成員變量傳值

首先,此處的成員變量signal聲明為RACSignal類(lèi),是RACPassthroughSubscriber類(lèi)實(shí)例化方法執(zhí)行時(shí)傳入的。而該信號(hào)又是從RACDynamicSignal傳來(lái)的,RACDynamicSignal持有了當(dāng)前的subscribe;subscribe繼續(xù)向上溯源,找到了在RACSignal類(lèi)中的[self subscribe:o]方法。那么答案已經(jīng)顯而易見(jiàn)了,unsafe_unretained屬性的聲明,就是為了防止在此過(guò)程中的循環(huán)引用。


RACSignal弱引用導(dǎo)圖

在RACSignal類(lèi)的訂閱方法subscribeNext方法中,當(dāng)執(zhí)行訂閱信號(hào)時(shí),self通過(guò)LLDB打印出的卻是RACDynamicSignal類(lèi)。


self打印信息

首先RACDynamicSignal類(lèi)是RACSignal類(lèi)的子類(lèi),此處進(jìn)行了RACSignal類(lèi)的分類(lèi)擴(kuò)展在分類(lèi)中實(shí)現(xiàn)了subscribeNext方法。在創(chuàng)建信號(hào)時(shí),信號(hào)類(lèi)為RACDynamicSignal類(lèi)。


RACSignal分類(lèi)

在發(fā)送信號(hào)時(shí),打印subscriber會(huì)發(fā)現(xiàn)其所屬類(lèi)為RACPassthroughSubscriber。


打印結(jié)果

self.innerSubscriber對(duì)象為RACSubscriber類(lèi)創(chuàng)建的,最終是執(zhí)行RACSubscriber類(lèi)下的sendNext方法,執(zhí)行nextBlock。在執(zhí)行時(shí),@synchronized (self)用于保證線程安全

RACPassthroughSubscriber發(fā)送信號(hào)實(shí)現(xiàn)

以上就是針對(duì)RACPassthroughSubscriber類(lèi)的實(shí)現(xiàn)進(jìn)行了一個(gè)簡(jiǎn)單的分析,后續(xù)會(huì)不斷補(bǔ)充、修改。


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

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