1.MVVM 代替 MVC 原因
無論MVC還是MVVM摆寄,包括其他設(shè)計模式靶衍,核心目的是為了提高代碼的簡潔性酪我,降低耦合度司浪。
簡單點說就是讓專門的人去做專門的事情泊业。
比如MVC模式中,
但在MVC中啊易,通過網(wǎng)絡(luò)請求回來的數(shù)據(jù)會放到Model中吁伺,作為數(shù)據(jù)源來調(diào)用和處理。
但還是存在控制器中文件很大的問題租谈。很多業(yè)務(wù)邏輯都寫到了控制器上了篮奄,不利于程序之間的解耦,而且在比較大的項目中,代碼的可讀性也比較差窟却,而MVVM的引入大大減少了這個問題昼丑,會讓C釋放釋放出來,關(guān)于視圖方面的業(yè)務(wù)邏輯交給VM處理夸赫,C只用來解決控制器之間的連接問題菩帝。
2.RAC如何處理和傳輸數(shù)據(jù)
那在RAC中怎么處理和傳送數(shù)據(jù)呢?
RAC最核心的內(nèi)容是信號茬腿。我們可以把網(wǎng)絡(luò)請求回來的數(shù)據(jù)通過信號傳遞和發(fā)送出去呼奢。
我們把網(wǎng)絡(luò)請求回來的數(shù)據(jù)叫做responseObject。
基于RAC的知識滓彰,我們讓訂閱者發(fā)送數(shù)據(jù)控妻,然后讓信號接收數(shù)據(jù)州袒,便完成數(shù)據(jù)的傳遞揭绑。
同時RAC中有RACCommand的類,負(fù)責(zé)處理事件郎哭。
所有總體可以分為三步:
- 網(wǎng)絡(luò)請求他匪,獲得數(shù)據(jù)responseObject;
- 訂閱者將responseObject發(fā)送出去夸研;
- 信號訂閱信號(接收發(fā)送處理的數(shù)據(jù))邦蜜。
3.代碼實例
至于代碼層面是怎么解決這三個方面的問題呢?
我們假設(shè)一個使用場景:
豆瓣上有開放的API,當(dāng)我們查詢圖書的時候亥至,當(dāng)搜索"美女"關(guān)鍵詞的時候悼沈,會出現(xiàn)很多關(guān)于美女的圖書。
然后將其顯示在tableView上姐扮。
主要的業(yè)務(wù)邏輯包括:
- 通過AFN請求數(shù)據(jù)
- 將請求回來的數(shù)據(jù)傳遞給控制器
- 控制器的tableView完成數(shù)據(jù)的顯示
3.1 AFN請求數(shù)據(jù)
AFHTTPRequestOperationManager *mgr = [AFHTTPRequestOperationManager manager];
[mgr GET:@"https://api.douban.com/v2/book/search" parameters:@{@"q":@"美女"} success:^(AFHTTPRequestOperation * _Nonnull operation, NSDictionary * _Nonnull responseObject) {
NSLog(@"發(fā)送成功");
NSArray *dictArray = responseObject[@"books"];
[subscriber sendNext:dictArray];
3.2請求回來的數(shù)據(jù)傳給控制器
在MVC中絮供,通常會將請求回來的數(shù)據(jù)responseObject進(jìn)行初步的處理,放到model模型中茶敏,然后tableView的數(shù)據(jù)源也來自于模式壤靶,最終玩徹骨tableView的繪制和展示。
這里我們通過MVVM的方式惊搏,將網(wǎng)絡(luò)請求的業(yè)務(wù)邏輯放到VM中處理贮乳。在V中實現(xiàn)tableView的數(shù)據(jù)源方法。
至于事件的處理就交給RAC來解決恬惯。RAC中有一個類RACCommond向拆,來處理事件。
3.3具體代碼
//通過RACCommand獲取數(shù)據(jù)
- (void)getData {
self.requestCommand = [[RACCommand alloc]initWithSignalBlock:^RACSignal *(id input) {
RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
AFHTTPRequestOperationManager *mgr = [AFHTTPRequestOperationManager manager];
[mgr GET:@"https://api.douban.com/v2/book/search" parameters:@{@"q":@"美女"} success:^(AFHTTPRequestOperation * _Nonnull operation, NSDictionary * _Nonnull responseObject) {
NSLog(@"發(fā)送成功");
NSArray *dictArray = responseObject[@"books"];
[subscriber sendNext:dictArray];
} failure:^(AFHTTPRequestOperation * _Nonnull operation, NSError * _Nonnull error) {
NSLog(@"發(fā)送失敗");
}];
return nil;
}];
return signal;
}];
}
//控制器接受傳回來的數(shù)據(jù)
- (void)getDataFromRequestVM {
RACSignal *signal = [self.requestVM.requestCommand execute:nil];
[signal subscribeNext:^(id x) {
self.dataArray = x;
[self.tableView reloadData];
}];
}
4.注意:
為了避免外部修改酪耳,可以使用readOnly
以上操作可以分步處理浓恳,也可以通過RACCommand的類來處理。
此文章原文鏈接自己的個人博客: www.koalaliu.com ,歡迎來訪。因簡書平臺規(guī)范性以及用戶量奖蔓,搬至簡書赞草。