在實際項目開發過程中,經常會在多處不同地方對同一信號進行訂閱。比如:在網絡請求時,收到返回數據要針對頁面多處進行更新操作。
通常會出現以下RAC寫法:
一個信號多個訂閱者的錯誤示范
這樣的錯誤寫法打印結果如下:
錯誤示范的打印結果
從打印結果來看,很明顯地RACSignal擁有兩個訂閱者時,發送信號與銷毀信號都執行了兩次。當擁有更多訂閱者或者需要在發送信號前耗時處理時,這種寫法大大降低了運行效率,浪費了不必要的資源。
針對這種情況,就需要使用
RACMulticastConnection
來處理。將上述問題代碼加入進
RACMulticastConnection
處理之后引入RACMulticastConnection之后
這時再查看打印結果
引入RACMulticastConnection打印結果
發送信號時只執行了一次,兩個訂閱者都收到了各自的訂閱信號。
為什么RACMulticastConnection
可以實現一次發送多處訂閱者就可以收到信號?
帶著問題去查看其內部實現過程
publish方法實現
從上圖代碼實現中,可以發現
RACMulticastConnection
是基于RACSubject
來實現的,并將RACSubject
封裝成了RACMulticastConnection
對象。打印connection.signal
,可以發現是為RACSubject
類的對象。再繼續進入至
- (instancetype)initWithSourceSignal:(RACSignal *)source subject:(RACSubject *)subject
方法中。RACMulticastConnection內部實現方法
此處使用了方法
bool OSAtomicCompareAndSwap32Barrier( int32_t __oldValue, int32_t __newValue, volatile int32_t *__theValue );
用于將
_hasConnected
與0(oldValue)
進行比較,如果兩者是匹配的,則方法結果返回YES并將_hasConnected
賦值為1(newValue)
。即由未連接狀態,修改成已連接狀態。當由未連接狀態變為已連接狀態時,執行信號的訂閱方法。
總結一下RACMulticastConnection實現過程:
1.創建connect
,connect.sourceSignal
-> RACSignal(原始信號) connect.signal
-> RACSubject
2.訂閱connect.signal
,會調用RACSubject
的subscribeNext
,創建訂閱者,而且把訂閱者保存起來,不會執行block。
3.[connect connect]
內部會訂閱RACSignal(原始信號)
,并且訂閱者是RACSubject
4.RACSubject
的sendNext
,會遍歷RACSubject
所有訂閱者發送信號,并執行他們的nextBlock( )
該文章首次發表在 簡書:我只不過是出來寫寫代碼 博客,并自動同步至 騰訊云:我只不過是出來寫寫iOS 博客