ReactiveCocoa (RAC) 框架

發表於2016-10-19

前言

本文是根據DeveloperLx在鬥魚直播ReactiveCocoa時整理的文章,同時加上本人的見解,若有錯誤希望指出。
感謝 DeveloperLx 為大家做出的貢獻,雖然直播聲音小了點,但滿滿的都是乾貨 ^v^

簡介

神馬是RAC?ReactiveCocoa(簡稱為RAC),是由Github開源的一個應用於iOS和OS開發的新框架,Cocoa是蘋果整套框架的簡稱,因此很多蘋果框架喜歡以Cocoa結尾。借用RayWenderlich上面的話:

As an iOS developer, nearly every line of code you write is in reaction to some event; a button tap, a received network message, a property change (via Key Value Observing) or a change in user’s location via CoreLocation are all good examples. However, these events are all encoded in different ways; as actions, delegates, KVO, callbacks and others. ReactiveCocoa defines a standard interface for events, so they can be more easily chained, filtered and composed using a basic set of tools.

翻譯過來就是:

作為一個iOS開發者,你寫的每一行程式碼幾乎都是在響應某個事件,例如按鈕的點選,收到網路訊息,屬性的變化(通過KVO)或者使用者位置的變化(通過CoreLocation)。但是這些事件都用不同的方式來處理,比如action、delegate、KVO、callback等。ReactiveCocoa為事件定義了一個標準介面,從而可以使用一些基本工具來更容易的連線、過濾和組合。

RAC是由 Mattt Thompson 大神開發的,很多開發者對其的評價是開啟一個新Objective-C紀元,可見對其評價有多高。
以下是RAC的Github主頁:ReactiveCocoa
以及官方給出的用法連結

安裝

ReactiveCocoa安裝教程我就不說了,用pod安裝即可。
本文的Demo可在文章最後下載,在閱讀本文的時候,強烈推薦邊看Demo邊看博文。
專案中加入了ReactiveCocoa 和 DeveloperLx 大神的列印外掛 LxDBAnything
同時加入了鍵盤相應的第三方IQKeyboardManager,然而沒有怎麼用到。
以及Masonry,使用方法可以看這篇文章,iOS – Masonry自動佈局(Autolayout)

擼程式碼

第一部分 簡單使用

文字框事件

原來我們在使用textFiled的時候我們需要寫到

然後實現textChanged:方法,在RAC中,對於文字框的監聽,是非常簡單的一件事情,看如下程式碼:

列印結果:

我們很容易的監聽到textFiled中發生的變化,其中x的型別預設為id型別, 我們已知它的型別的時候我們可以將其改變,就像上面程式碼,將id改成了NSString型別。

手勢

為了方便,我們直接新增到self.view上,點選螢幕,得到列印結果:

通知

我們建立了一個通知,叫做進入後臺, 當程式進入後臺的時候通知相應,當我們用RAC寫通知的時候,我們有一個好處,就是不用removeObserver通知,因為RAC通知的監聽者師RAC自己,它會幫你管理釋放方法。可以看方法實現如下:

定時器

這是定時器最常用的兩種寫法,第一種方法,延遲時間去做某件事,更改afterDelay的屬性。
第二種方法,每間隔多長時間做一件事,更改interval屬性。

代理

用RAC去寫代理的時候,會有侷限,只能取代沒有返回值的代理方法,什麼是沒有返回值的代理呢?比如說tableView的代理方法:

這兩個方法一個返回的是CGFloat,一個是void,RAC只能取代void的代理。

KVO

用RAC寫KVO的好處就是方法簡單,keypath有程式碼提示。

第二部分 進階

訊號

RAC的核心就是RACSignal,也就是訊號,我們可以直接建立訊號createSignal,併傳送它sendNext,當訊號完成後我們同時用dispose方法銷燬它。傳送訊號,我們同時也要訂閱訊號,訂閱訊號程式碼如下:

在訊號傳送的時候, 錯誤的時候,以及完成的時候,我們都可以得到相應。

訊號的處理

map (對映)

map這個函式,在這裡不是地圖的意思,代表對映。map能做的事情就是把監聽的rac_textSignal所返回的值,替換成別的就像上面程式碼中的text的長度。

filter

為了方便演示,我就不再賦值建立textField的程式碼了,請到Demo中檢視

filter是個BOOL值,它代表的是一個條件,當這個條件發生的時候才會作出相應,比如上面程式碼中,當長度大於3的時候,才會列印x的值。

delay

delay的作用就是延遲,或者說等待,如上,等待2秒之後列印了x。

startWith

startWith也就是最開始的意思,看以上程式碼 startWith:@"123"等同於[subscriber sendNext:@"123"] 也就是第一個傳送,主要是位置.

timeOut

上面程式碼的意思就是,我等待3秒中傳送(afterDelay),但是我超時了(timeout)2秒鐘才傳送,所以這條資訊發生錯誤,會走error的方法。 這種情況可以用在封裝http client中,當然你可能遇到別的需求,也需要它。

take – skip

比如說我們傳送了很多次請求

take表示我們只取前兩次
skip表示跳過前兩次
takeLast表示倒數的前兩次
takeUntil這個值比較特殊,他後面的引數是個訊號,它的意思是,當takeUntil傳送這個訊號的時候,上面的傳送訊號就會停止傳送。

接下來是幾個block回撥方法

takeWhileBlock BOOL值,意思是當返回YES的時候,訂閱者才能收到訊號
skipWhileBlock BOOL值,意思是當返回YES的時候,訂閱者就會跳過訊號,NO的時候才接受
skipUntilBlock BOOL值,意思是 返回NO的時候,不會收到訊息, 直到返回YES的時候才開始收訊息。

即時搜尋優化 (throttle,distinctUntilChanged,ignore)

以上程式碼,是用textField模擬一個即時搜尋優化的功能,其中引數如下:

throttle 後面是個時間 表示rac_textSignal傳送訊息,0.3秒內沒有再次傳送就會相應,若是0.3內又傳送訊息了,便會在新的資訊處重新計時
distinctUntilChanged 表示兩個訊息相同的時候,只會傳送一個請求
ignore 表示如果訊息和ignore後面的訊息相同,則會忽略掉這條訊息,不讓其傳送

這樣做,是不是給伺服器減小了很多的壓力,更是節省了我們大量的程式碼。 其中我們用map建立了一個新的訊號,我們知道textField的改變是一個訊號, map就是在這個訊號上,又加了一個訊號,即signal of signals
訂閱者所列印的訊息x則是,map發出的訊號。我們可以再map中傳送新的訊號,以及取消訊號disposable.
當我們用map傳送訊號的時候,我們則需要使用 switchToLatest這個引數來獲取最後一個訊號,也就是我們最後所列印的x,就是map最後發錯的這個訊號。

repeat

repeat,顧名思義,就是重複傳送這條訊息,當我們在後面新增了delay和take的時候,意思就是每隔1秒傳送一次這條訊息,傳送3次後停止。

merge – concat – zipWith

我們建立了兩個請求,A和B,用GCD的方法A延遲兩秒鐘,B延遲了3秒鐘,我們用merge方法合併了A和B,列印結果為

也就是A和B不管誰傳送都會列印x,簡單的說就是A和B的列印方法用的是同一個。他們之間關係是獨立的,如果A傳送失敗,B依然會執行。

當我們用concat方法連結A和B之後,意思就是當A執行完了之後才會執行B,他們之間是依賴的關係,如果A傳送失敗,B也不會執行。

請注意合併(merge)和連結(concat)的區別。

zipWith,當用zipWith連結A和B的時候,只有在A.B每隔都至少傳送過一次訊息的時候才會執行zipWith的方法,它的返回值是一個集合,也就是陣列,同時包含了A和B的列印結果。
zipWith的寫法等同於 :

亦或者

但是使用combineLatest,可以再後面新增更多的訊號.

RAC() 巨集

比如Btn的設定背景顏色的屬性,OC中並沒有button setBackgroundColor:forState:這種方法,我們不能直接設定其選中後的顏色。在RAC中,則可以很簡單的改變BTN的背景顏色。不得不說RAC的簡單和強大。

做一個秒錶

只有這麼多程式碼,我們便可以完美的做一個秒錶,是否很cool?

rac

結束

當我們大量使用RAC寫程式碼的時候,會把一個個事件封裝成一個個訊號,通過觸發訊號,訂閱這個訊號來返回各種資訊。RAC使我們的程式碼耦合性根底,聚合性更高。

若有不懂得地方可以留言,若有寫錯的地方,請及時與我聯絡,可以留言或者Email等。

文字所用的Demo,下載地址 戳這裡.

相關文章