網(wǎng)上關(guān)于RAC和MVVM的資料非常多筋岛,我寫這篇主要是因?yàn)槌鯇W(xué)RAC,為自己記個(gè)學(xué)習(xí)筆記告抄。
1. RAC是什么痒玩?
(1) ReactiveCocoa(簡(jiǎn)稱RAC)是github開源的一款cocoa FRP框架。FRP通過信號(hào)記錄值的變化搂妻,信號(hào)可以被疊加蒙保、分割或合并,通過對(duì)信號(hào)的組合欲主,就不需要去監(jiān)聽某個(gè)值的變化或事件的發(fā)生邓厕。
(2) RAC主要有兩個(gè)作用:1)RAC的信號(hào)機(jī)制可以將ViewModel與View相關(guān)聯(lián)逝嚎,這樣View的變化可以直接響應(yīng)ViewModel層的變化。2)統(tǒng)一消息傳遞機(jī)制详恼。iOS中消息傳遞機(jī)制有很多:delegate补君、notification、KVO昧互、block挽铁、target-action等,使用時(shí)會(huì)不困惑選擇哪種方式最優(yōu)敞掘,RAC通過增加category的方式將傳統(tǒng)的UI控件事件進(jìn)行了封裝叽掘,提供一個(gè)統(tǒng)一的接口,簡(jiǎn)化了消息傳遞機(jī)制玖雁。用ARC來完成消息傳遞機(jī)制代碼實(shí)現(xiàn):
// KVO
[RACObserve(self, text) subscribeNext:^(id text) {
NSLog(@" 成員變量 text 被修改成了:%@", text);
}];
// target-action
self.button.rac_command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
NSLog(@" 按鈕被點(diǎn)擊 ");
}];
// Notification
[[[NSNotificationCenter defaultCenter]
rac_addObserverForName:notificationName
object:nil]
subscribeNext:^(id x) {
NSLog(@" 收到通知notificationName ");
}
];
// Delegate
[[self rac_signalForSelector:@selector(viewWillAppear:)] subscribeNext:^(id x) {
debugLog(@"viewWillAppear 方法被調(diào)用 %@", x);
}];
(3) 信號(hào)是指一個(gè)發(fā)送一連串值(event)的object更扁,當(dāng)有subscriber監(jiān)聽時(shí),signal才會(huì)發(fā)送消息赫冬。
2. RAC中的熱信號(hào)與冷信號(hào)
1)各自特點(diǎn):熱信號(hào)類似“直播”浓镜,錯(cuò)過了就不再處理(不會(huì)收到訂閱之前的數(shù)據(jù))。而冷信號(hào)類似“點(diǎn)播”面殖,每次訂閱都會(huì)從頭開始竖哩。
2)RAC4中的signalProducer對(duì)應(yīng)RAC2中的RACSignal是冷信號(hào);RAC4中的signal對(duì)應(yīng)RAC2中的RACSubject是熱信號(hào)脊僚。
3)如果冷信號(hào)中包含網(wǎng)絡(luò)請(qǐng)求相叁,那么每次訂閱這個(gè)冷信號(hào)都會(huì)發(fā)送網(wǎng)絡(luò)請(qǐng)求,而且任何的信號(hào)轉(zhuǎn)換即是對(duì)原有的信號(hào)進(jìn)行訂閱從而產(chǎn)生新的信號(hào)辽幌。這將對(duì)用戶流量增淹、服務(wù)器負(fù)載造成不好的影響。因此要區(qū)分冷熱信號(hào)乌企。
4)上述問題的解決方法就是將冷信號(hào)轉(zhuǎn)換成特殊的熱信號(hào)虑润。在RAC4中,我們使用SignalProducer.buffer(Int)這個(gè)方法來代替RACReplaySubject加酵,這樣即使訂閱者在信號(hào)發(fā)送事件之后訂閱拳喻,也可以收到信號(hào)發(fā)送的所有事件,就像所有的事件緩存起來一樣猪腕,這里就像冷信號(hào)一樣冗澈,同時(shí)又不會(huì)有副作用。
3. MVVM:MVC的增強(qiáng)版
構(gòu)造ViewModel陋葡,主要是 ViewController 給 View 傳遞數(shù)據(jù)的這個(gè)過程亚亲,抽象成構(gòu)造 ViewModel 的過程。這樣抽象后,View只接收ViewModel捌归,而Controller只需要傳遞ViewModel肛响,簡(jiǎn)化了Controller文件,也更加容易測(cè)試惜索。