ReactiveCocoa學習

版本

到我寫這篇文章為止,ReactiveCocoa版本為5.0.1,搜了很多博客來了解ReactiveCocoa的基礎用法,并不是很多,所以這篇文章算是自己對搜索資源的一個匯總,并加入一些自己在學習中遇到的問題和解決.

RAC 5.0 相比于 4.0 有了巨大的變化,不僅是受 swift 3.0 大升級的影響,RAC 對自身項目結(jié)構(gòu)的也進行了大幅度的調(diào)整。這個調(diào)整就是將 RAC 拆分為四個庫:ReactiveCocoa, ReactiveSwift, ReactiveObjC, ReactiveObjCBridge.

在項目里現(xiàn)在到底要引入哪些

如果你的項目是純 OC 項目,你需要使用的是 ReactiveObjC 。這個庫里面包含原來 RAC 2 的全部代碼。
如果你只是純 swift 項目,你繼續(xù)使用ReactiveCocoa 。但是 RAC 依賴于 ReactiveSwift ,等于你引入了兩個庫。
如果你的項目是 swift 和 OC 混編,你需要同時引用 ReactiveCocoa 和 ReactiveObjCBridge 。但是 ReactiveObjCBridge 依賴于 ReactiveObjC ,所以你就等于引入了 4 個庫。


ReactiveCocoa 試圖解決什么問題

  1. 傳統(tǒng) iOS 開發(fā)過程中,狀態(tài)以及狀態(tài)之間依賴過多的問題
  2. 傳統(tǒng) MVC 架構(gòu)的問題:Controller 比較復雜,可測試性差
  3. 提供統(tǒng)一的消息傳遞機制

傳統(tǒng) iOS 開發(fā)過程中,狀態(tài)以及狀態(tài)之間依賴過多的問題

我們在開發(fā) iOS 應用時,一個界面元素的狀態(tài)很可能受多個其它界面元素或后臺狀態(tài)的影響。
例如,在用戶帳戶的登錄界面,通常會有 2 個輸入框(分別輸入帳號和密碼)和一個登錄按鈕。如果我們要加入一個限制條件:當用戶輸入完帳號和密碼,并且登錄的網(wǎng)絡請求還未發(fā)出時,確定按鈕才可以點擊。通常情況下,我們需要監(jiān)聽這兩個輸入框的狀態(tài)變化以及登錄的網(wǎng)絡請求狀態(tài),然后修改另一個控件的enabled狀態(tài)。
RAC 通過引入信號(Signal)的概念,來代替?zhèn)鹘y(tǒng) iOS 開發(fā)中對于控件狀態(tài)變化檢查的代理(delegate)模式或 target-action 模式。因為 RAC 的信號是可以組合(combine)的,所以可以輕松地構(gòu)造出另一個新的信號出來,然后將按鈕的enabled狀態(tài)與新的信號綁定。

RAC(self.loginBtn,enabled) = [RACSignal combineLatest:@[self.nameTF.rac_textSignal,
                                                        self.passwordTF.rac_textSignal
                                                        ]
                                                reduce:^(NSString *nameSignal,NSString *pwdSignal){
                                                            return @(nameSignal.length>=0 && pwdSignal.length>=0);
                                                        }];

簡單的解釋一下代碼:
這是將loginBtn的enable屬性和帳號和密碼兩個輸入框綁定,當兩個輸入框的文本都不為空的時候,loginBtn才可以點擊. 注意一點,reduce后面的block并不會自動生成所有的返回值,需要根據(jù)自己在前面綁定的幾個信號自己補全,然后直到這部分代碼完全寫完中間可能一直在報錯,不要理他.從RAC的源碼中可以看出來,前面綁定的信號不同后面的block返回值類型也是不同的.

統(tǒng)一消息傳遞機制

iOS 開發(fā)中有著各種消息傳遞機制,包括 KVO、Notification、delegation、block 以及 target-action 方式。各種消息傳遞機制使得開發(fā)者在做具體選擇時感到困惑. 在引入 RAC 之后,以前散落在action-target或 KVO 的回調(diào)函數(shù)中的判斷邏輯被統(tǒng)一到了一起.

// KVO
[RACObserve(self, username) subscribeNext:^(id x) {
    NSLog(@" 成員變量 username 被修改成了:%@", x);
}];
// target-action
self.button.rac_command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
    NSLog(@" 按鈕被點擊 ");
    return [RACSignal empty];
}];
// Notification
[[[NSNotificationCenter defaultCenter] 
    rac_addObserverForName:UIKeyboardDidChangeFrameNotification         
                    object:nil] 
    subscribeNext:^(id x) {
        NSLog(@" 鍵盤 Frame 改變 ");
    }
];
// Delegate
[[self rac_signalForSelector:@selector(viewWillAppear:)] subscribeNext:^(id x) {
    debugLog(@"viewWillAppear 方法被調(diào)用 %@", x);
}];

基礎用法理解參考下面這篇文章吧,是翻譯過來的,寫得很棒,例子層層深入,慢慢讀,就理解RAC的signal了.不過個人感覺想要深入了解,還是得自己多用.
ReactiveCocoa入門教程——第一部

試圖解決 MVC 框架的問題

對于傳統(tǒng)的 Model-View-Controller 的框架,Controller 很容易變得比較龐大和復雜。由于 Controller 承擔了 Model 和 View 之間的橋梁作用,所以 Controller 常常與對應的 View 和 Model 的耦合度非常高,這同時也造成對其做單元測試非常不容易,對 iOS 工程的單元測試大多都只在一些工具類或與界面無關(guān)的邏輯類中進行。
RAC 的信號機制很容易將某一個 Model 變量的變化與界面關(guān)聯(lián),所以非常容易應用 Model-View-ViewModel 框架。通過引入 ViewModel 層,然后用 RAC 將 ViewModel 與 View 關(guān)聯(lián),View 層的變化可以直接響應 ViewModel 層的變化,這使得 Controller 變得更加簡單,由于 View 不再與 Model 綁定,也增加了 View 的可重用性。

MVVM 的作用和問題
MVVM 在實際使用中,確實能夠使得 Model 層和 View 層解耦,但是如果你需要實現(xiàn) MVVM 中的雙向綁定的話,那么通常就需要引入更多復雜的框架來實現(xiàn)了。
對此,MVVM 的作者 John Gossman 的 批評 應該是最為中肯的。John Gossman 對 MVVM 的批評主要有兩點:

第一點:數(shù)據(jù)綁定使得 Bug 很難被調(diào)試。你看到界面異常了,有可能是你 View 的代碼有 Bug,也可能是 Model 的代碼有問題。數(shù)據(jù)綁定使得一個位置的 Bug 被快速傳遞到別的位置,要定位原始出問題的地方就變得不那么容易了。
第二點:對于過大的項目,數(shù)據(jù)綁定需要花費更多的內(nèi)存。

附:
之前在上家公司用過一個MBMvc的框架來幫助分層,很好用,不過我看了一下github上已經(jīng)很久沒有更新了,懷疑是不是有什么問題停更了呢, 大家有興趣的可以了解一下這個框架.


摘自:
唐巧 : ReactiveCocoa - iOS開發(fā)的新框架

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容