學習ReactiveCocoa中的一個疑惑

最近在學習ReactiveCocoa,驚異于響應式編程強大的能力之余恨胚,發(fā)現(xiàn)了一個有疑惑的點骂因。
ReactiveCocoa的核心在于萬物皆信號炎咖,響應式編程簡單比喻就是多米諾骨牌赃泡,牽一發(fā)動全身。

網(wǎng)上找了些簡單demo乘盼,大多是登錄場景的小demo升熊,輸出賬號校驗格式再提交什么的〕裾ぃ基本代碼如下

ViewModel.h

@interface ViewModel : NSObject

@property (nonatomic, strong) NSString *account;
@property (nonatomic, strong) RACCommand *buttonCommand;

@end

ViewModel.m

- (RACCommand *)subscribeCommand {
    if (!_subscribeCommand) {
        @weakify(self);
        _subscribeCommand = [[RACCommand alloc] initWithEnabled:self.validSignal signalBlock:^RACSignal *(id input) {
                        **
                        提交賬號密碼
                        */
            return nil;
        }];
    }
    return _subscribeCommand;
}
- (RACSignal *)accountValidSignal {
    if (!_accountValidSignal) {
        _accountValidSignal = [RACObserve(self, account) map:^id(NSString *string) {
            return @(account.length > 5);
        }];
    }
    return _accountValidSignal;
}

ViewController.m

@implementation ViewController
- (void)viewDidLoad {
    **
    省略
    */
}
- (void)bindViewModel {
    RAC(self.viewModel, account) = self.account.rac_textSignal;
    self.submitButton.rac_command = self.viewModel.buttonCommand;
}
**
省略其他部分代碼
*/
@end

很簡單的demo级野,響應用戶輸入TextField,ViewModel的account可以一并更新粹胯,并且實時更新button狀態(tài)蓖柔。

好,看到這幾行风纠,你是不是完全沒有疑問况鸣,一個很簡單的MVVM的小demo而已。

我昨天也是這么想的竹观。

今天無意間看了幾行ReactiveCocoa的源碼镐捧。

RACCommand.h

@interface RACCommand : NSObject
**
省略
*/
/// A signal of whether this command is currently executing.
///
/// This will send YES whenever -execute: is invoked and the created signal has
/// not yet terminated. Once all executions have terminated, `executing` will
/// send NO.
///
/// This signal will send its current value upon subscription, and then all
/// future values on the main thread.
@property (nonatomic, strong, readonly) RACSignal *executing;

/// A signal of whether this command is able to execute.
///
/// This will send NO if:
///
///  - The command was created with an `enabledSignal`, and NO is sent upon that
///    signal, or
///  - `allowsConcurrentExecution` is NO and the command has started executing.
///
/// Once the above conditions are no longer met, the signal will send YES.
///
/// This signal will send its current value upon subscription, and then all
/// future values on the main thread.
@property (nonatomic, strong, readonly) RACSignal *enabled;
**
省略
*/
@end

發(fā)現(xiàn)ReactiveCocoa框架里定義的屬性,幾乎都定義為RACSignal類型臭增,仔細想了下懂酱,確實這樣更符合ReactiveCocoa的核心思想,萬物皆信號誊抛。

看完這個之后列牺,我決定把上面的demo改一改:

ViewModel.h

@interface ViewModel : NSObject

@property (nonatomic, strong) RACSignal<NSString *> *account;

@property (nonatomic, strong) RACCommand *command;

@end

ViewModel.m

@interface 
@end
@implementation
- (RACCommand *)subscribeCommand {
    if (!_subscribeCommand) {
        @weakify(self);
        _subscribeCommand = [[RACCommand alloc] initWithEnabled:self.validSignal signalBlock:^RACSignal *(id input) {
                        **
                        提交賬號密碼
                        */
            return nil;
        }];
    }
    return _subscribeCommand;
}
- (RACSignal *)accountValidSignal {
    if (!_accountValidSignal) {
        _accountValidSignal = [RACObserve(self, account) map:^id(NSString *string) {
            return @(account.length > 5);
        }];
    }
    return _accountValidSignal;
}

ViewController.m

@implementation ViewController
- (void)viewDidLoad {
    **
    省略
    */
}
- (void)bindViewModel {
    self.vm.account = self.account.rac_textSignal;
    self.submitButton.rac_command = self.viewModel.buttonCommand;
}
**
省略其他部分代碼
*/
@end

這樣看代碼是不是更簡潔,更直觀拗窃。

很多人會問昔园,那ViewModel的account值怎么從外部set呢?

這就牽涉到整體框架的數(shù)據(jù)流轉問題了并炮。
大家知道默刚,數(shù)據(jù)的產(chǎn)生,基本上有兩個源頭逃魄,一個是網(wǎng)絡請求荤西,一個是用戶的action,在整個APP的開發(fā)過程中,其實我們就是一直在這兩個源頭的中間邪锌,做數(shù)據(jù)轉換和處理工作勉躺。

  • 將用戶的action傳遞給服務端,這里產(chǎn)生的數(shù)據(jù)觅丰,基本上都是在各種UI組件中輸入的饵溅,UIKit+ReactiveCocoa做了很強大的支持,幾乎所有輸入組件的value都已經(jīng)定義了各種RACsignal輸出妇萄,我們根本不需要set蜕企,因為set這個操作應該是用戶做的,不應該是代碼做的冠句,很完美轻掩!
  • 將服務端返回的數(shù)據(jù)展示給用戶,這里產(chǎn)生的數(shù)據(jù)懦底,基本上都是在網(wǎng)絡請求中獲取的唇牧,或者從本地的數(shù)據(jù)庫里拉的,以用的最多的AFNetworking為例聚唐,ReactiveCocoa也不忘為AFNetworking寫了一個category丐重,這邊的問題也解決了。

那這么寫有沒有問題呢杆查?

有扮惦。

MVVM相較于MVC來說,不僅是解決了Controller臃腫的問題根灯,也解決了Controller無法測試的問題径缅,ViewModel是可以測試的。
那么如果把ViewModel中的所有屬性轉化成RACSignal類型的話烙肺,測試就無法進行了纳猪,這在選型的時候是個很重要的問題。

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末桃笙,一起剝皮案震驚了整個濱河市氏堤,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌搏明,老刑警劉巖鼠锈,帶你破解...
    沈念sama閱讀 211,639評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異星著,居然都是意外死亡购笆,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評論 3 385
  • 文/潘曉璐 我一進店門虚循,熙熙樓的掌柜王于貴愁眉苦臉地迎上來同欠,“玉大人样傍,你說我怎么就攤上這事∑趟欤” “怎么了衫哥?”我有些...
    開封第一講書人閱讀 157,221評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長襟锐。 經(jīng)常有香客問我撤逢,道長,這世上最難降的妖魔是什么粮坞? 我笑而不...
    開封第一講書人閱讀 56,474評論 1 283
  • 正文 為了忘掉前任蚊荣,我火速辦了婚禮,結果婚禮上捞蚂,老公的妹妹穿的比我還像新娘妇押。我一直安慰自己跷究,他們只是感情好姓迅,可當我...
    茶點故事閱讀 65,570評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著俊马,像睡著了一般丁存。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上柴我,一...
    開封第一講書人閱讀 49,816評論 1 290
  • 那天解寝,我揣著相機與錄音,去河邊找鬼艘儒。 笑死聋伦,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的界睁。 我是一名探鬼主播觉增,決...
    沈念sama閱讀 38,957評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼翻斟!你這毒婦竟也來了逾礁?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,718評論 0 266
  • 序言:老撾萬榮一對情侶失蹤访惜,失蹤者是張志新(化名)和其女友劉穎嘹履,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體债热,經(jīng)...
    沈念sama閱讀 44,176評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡砾嫉,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,511評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了窒篱。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片焕刮。...
    茶點故事閱讀 38,646評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡蚓峦,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出济锄,到底是詐尸還是另有隱情暑椰,我是刑警寧澤,帶...
    沈念sama閱讀 34,322評論 4 330
  • 正文 年R本政府宣布荐绝,位于F島的核電站一汽,受9級特大地震影響,放射性物質發(fā)生泄漏低滩。R本人自食惡果不足惜召夹,卻給世界環(huán)境...
    茶點故事閱讀 39,934評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望恕沫。 院中可真熱鬧监憎,春花似錦、人聲如沸婶溯。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽迄委。三九已至褐筛,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間叙身,已是汗流浹背渔扎。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留信轿,地道東北人晃痴。 一個月前我還...
    沈念sama閱讀 46,358評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像财忽,于是被迫代替她去往敵國和親倘核。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,514評論 2 348

推薦閱讀更多精彩內(nèi)容