ReactiveCocoa理解

簡言

最近要將項目從 MVC 到 MVVM 遷移做組件化開發,
經過查閱資料發現 ReactiveCocoa為事件提供了很多處理方法,而且利用RAC處理事件很方便,可以把要處理的事情,和監聽的事情的代碼放在一起,這樣非常方便我們管理,就不需要跳到對應的方法里。非常符合我們開發中高聚合,低耦合的思想。
所以決定深入學習一下 RAC,本文章會持續更新并且上傳相應的 Demo 供大家指正

RAC

ReactiveCocoa簡稱RAC,就是基于響應式編程思想的Objective-C實踐,它是Github的一個開源項目

ReactiveCocoa框架概覽

RAC幾乎接管了Apple所有的事件機制,由于RAC將Cocoa中KVO、UIKit event、delegate、selector等都增加了RAC支持,所以都不用去做很多跨函數的事。
  • leezzhong的博客中有這樣的比喻,能讓你對ReactiveCocoa的信號傳遞有個很好的理解:

可以把信號想象成水龍頭,只不過里面不是水,而是玻璃球(value),直徑跟水管的內徑一樣,這樣就能保證玻璃球是依次排列,不會出現并排的情況(數據都是線性處理的,不會出現并發情況)。水龍頭的開關默認是關的,除非有了接收方(subscriber),才會打開。這樣只要有新的玻璃球進來,就會自動傳送給接收方。可以在水龍頭上加一個過濾嘴(filter),不符合的不讓通過,也可以加一個改動裝置,把球改變成符合自己的需求(map)。也可以把多個水龍頭合并成一個新的水龍頭(combineLatest:reduce:),這樣只要其中的一個水龍頭有玻璃球出來,這個新合并的水龍頭就會得到這個球。

Streams

Streams 表現為RACStream類,可以看做是水管里面流動的一系列玻璃球,它們有順序的依次通過,在第一個玻璃球沒有到達之前,你沒法獲得第二個玻璃球。 RACStream描述的就是這種線性流動玻璃球的形態,比較抽象,它本身的使用意義并不很大,一般會以signals或者sequences等這些更高層次的表現形態代替。

Signals

Signals 表現為RACSignal類,就是前面提到水龍頭,ReactiveCocoa的核心概念就是Signal,它一般表示未來要到達的值,想象玻璃球一個個從水龍頭里出來,只有了接收方(subscriber)才能獲取到這些玻璃球(value)。

Signal會發送下面三種事件給它的接受方(subscriber),想象成水龍頭有個指示燈來匯報它的工作狀態,接受方通過-subscribeNext:error:completed:對不同事件作出相應反應

  • next 從水龍頭里流出的新玻璃球(value)
  • error 獲取新的玻璃球發生了錯誤,一般要發送一個NSError對象,表明哪里錯了
  • completed 全部玻璃球已經順利抵達,沒有更多的玻璃球加入了
    一個生命周期的Signal可以發送任意多個“next”事件,和一個“error”或者“completed”事件(當然“error”和“completed”只可能出現一種)

Subjects

subjects 表現為RACSubject類,可以認為是“可變的(mutable)”信號/自定義信號,它是嫁接非RAC代碼到Signals世界的橋梁,很有用。嗯。。。 這樣講還是很抽象,舉個例子吧:

RACSubject:信號提供者,自己可以充當信號,又能發送信號。使用場景:通常用來代替代理,有了它,就不必要定義代理了

RACSubject *letters = [RACSubject subject];
RACSignal *signal = [letters sendNext:@"a"];
可以看到@''a"只是一個NSString對象,要想在水管里順利流動,就要借RACSubject的力。

RACReplaySubject

重復提供信號類,RACSubject的子類。

RACReplaySubject與RACSubject區別:RACReplaySubject可以先發送信號,再訂閱信號,RACSubject就不可以。

  • 使用場景一:如果一個信號每被訂閱一次,就需要把之前的值重復發送一遍,使用重復提供信號類。
  • 使用場景二:可以設置capacity數量來限制緩存的value的數量,即只緩充最新的幾個值。

Commands

command 表現為RACCommand類,可以認為是回應某些動作的信號,同常觸發該信號的動作都UI控件

Sequences

RAC中的集合類,用于代替NSArray,NSDictionary,可以使用它來快速遍歷數組和字典。

sequence 表現為RACSequence類,可以簡單看做是RAC世界的NSArray,RAC增加了-rac_sequence方法,可以使諸如NSArray這些集合類(collection classes)直接轉換為RACSequence來使用。

Schedulers

scheduler 表現為RACScheduler類,類似于GCD

RACTuple

元組類,類似NSArray,用來包裝值.

常用宏

  • RAC 可以看作某個屬性的值與一些信號的聯動
RAC(<#TARGET, ...#>)
RAC(self.submitButton.enabled) = [RACSignal combineLatest:@[self.usernameField.rac_textSignal, self.passwordField.rac_textSignal]
reduce:^id(NSString *userName, NSString *password) {
return @(userName.length &gt;= 6 &amp;&amp; password.length &gt;= 6);
}];
  • RACObserve 監聽屬性的改變,使用block的KVO
RACObserve(<#TARGET#>, <#KEYPATH#>)宏則用來生成一個對象的綁定屬性的信號量,
@property (nonatomic, strong) NSString* testText;
@property (nonatomic, strong) NSString* testText_2;

RAC(self,testText) = RACObserve(self, testText_2);
這個例子中,testText_2屬性有任何變動,都會通知給testText變成一樣的內容,
testText變化不會影響testText_2。RAC宏在等號左邊,右邊RACObserve宏返回一個傳值信號量。
  • UI Event
    RAC為系統UI提供了很多category,非常棒,比如UITextView、UITextField文本框的改動rac_textSignal,UIButton的的按下rac_command等等。

常用的方法

ReactiveCocoa常見的方法:

1 代替代理: rac_signalForSelector:用于替代代理。
2 代替KVO : rac_valuesAndChangesForKeyPath:用于監聽某個對象的屬性改變。
3 監聽事件: rac_signalForControlEvents:用于監聽某個事件。
4 代替通知: rac_addObserverForName:用于監聽某個通知。
5 監聽文本框文字改變:rac_textSignal:只要文本框發出改變就會發出這個信號。
6 處理當界面有多次請求時,需要都獲取到數據時,才能展示界面;rac_liftSelector:withSignalsFromArray:Signals:當傳入的Signals(信號數組),每一個signal都至少sendNext過一次,就會去觸發第一個selector參數的方法。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容