iOS 架構(gòu)模式

MVC-面向?qū)ο?/h1>
image

以上三者的交互關(guān)系。什么關(guān)系?

  1. Model 不與 View直接通話取视,如圖中Model和View之間的兩黃實線。
  2. Model 與 Controller 通話常挚,如圖中Model和Controller中兩灰色虛實線作谭、當(dāng)中的綠色箭頭、Model上橙色的KVO奄毡。
  3. View與 controller 通話折欠,如圖中Controller和View之間兩灰色虛實線、當(dāng)中的Outlet綠色箭頭吼过、黃色的delegate和data source锐秦。
  4. View上action 與 controller 上的target。
  5. Model上KVO發(fā)送端與controller上的黃色接受端盗忱。

MVC實際使用

目前App 中最常用的code習(xí)慣如下圖

image

通過這張圖可以發(fā)現(xiàn), 用戶信息頁面作為業(yè)務(wù)場景Scene需要展示多種數(shù)據(jù)M(Blog/Draft/UserInfo), 所以對應(yīng)的有多個View(blogTableView/draftTableView/image…), 但是, 每個MV之間并沒有一個連接層C, 本來應(yīng)該分散到各個C層處理的邏輯全部被打包丟到了Scene這一個地方處理, 也就是M-C-V變成了MM…-Scene-…VV, C層就這樣莫名其妙的消失了.

另外, 作為V的兩個cell直接耦合了M(blog/draft), 這意味著這兩個V的輸入被綁死到了相應(yīng)的M上, 復(fù)用無從談起.

MVC正常使用

那么正確的MVC是什么呢酱床?如下圖

image

MVC 的缺點

1、胖model的產(chǎn)生
2趟佃、Massive View Controller的產(chǎn)生
3扇谣、過度隔離V&M
4昧捷、產(chǎn)生太多輕量級的model
5、遺失網(wǎng)絡(luò)邏輯
6罐寨、較差的可測試性
7靡挥、業(yè)務(wù)邏輯與視圖邏輯強(qiáng)耦合

相關(guān)參考連接

http://www.reibang.com/p/7e5fc5fb7ba3
https://www.cnblogs.com/AnnieBabygn/p/7872552.html

MVP-面向接口

image

Model View Presenter


5.png

Controller中的所有邏輯都放在Presenter中實現(xiàn),與MVC不同的是Model與View是沒有任何聯(lián)系的衩茸,都是通過Presenter來交互

Presenter持有MVPView與MVPModel

#import "MVPViewController.h"
#import "Presenter.h"
#import "MVPModel.h"
#import "MVPView.h"
@interface MVPViewController () 
@property (nonatomic, strong) Presenter *presenter;
@property (nonatomic, strong) MVPView  *mvpView;
@property (nonatomic, strong) MVPModel *mvpModel;
@end
@implementation MVPViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    _presenter = [[Presenter alloc] init];
    _mvpView = [[MVPView alloc] init];
    _mvpView.frame = self.view.bounds;
    [self.view addSubview:_mvpView];
    _mvpModel = [MVPModel new];
    _mvpModel.content = @"MVP的模式";
    // model還沒賦值
    _presenter.model = _mvpModel;
    _presenter.view = _mvpView;
    [_presenter usageLogic];
}
@end

MVVM-響應(yīng)式編程

MVVM其實是MVC的升級版芹血,controller & view 直接通過viewModel 讀取數(shù)據(jù)然后展示在界面上

MVVM概念

7.png

MVVM 簡單一點說 : 雙向綁定(通過viewModel 綁定view 與 model)

使用的嚴(yán)格限制

1、View 引用了viewModel 楞慈,但是反過來不行
2幔烛、viewModel引用了model,但是反過來不行
3囊蓝、MVVM模式依賴于數(shù)據(jù)綁定饿悬,它是一個框架級別的特性,用于自動連接對象屬性和UI控件聚霜。

viewModel 主要通過以下兩種方式通知View更新UI

1狡恬、Block
2、使用reactiveCocoa庫

這個庫包含了函數(shù)式編程和響應(yīng)式編程蝎宇。其實reactiveCocoa庫就是MVVM模式的核心弟劲。
不使用 RAC :ViewModel處理完數(shù)據(jù)需要刷新 View等操作都是通過 Block回調(diào)來實現(xiàn),不免是有些麻煩的姥芥。
使用 RAC :在 View初始化的時候就和 ViewModel進(jìn)行綁定兔乞,只要 ViewModel的數(shù)據(jù)有所變化,便自動更新 View凉唐。
RAC 缺點:數(shù)據(jù)綁定使得一個位置的 Bug被快速傳遞到別的位置庸追,要定位原始出問題的地方就變得不那么容易了

ReactiveCocoa

reactiveCocoa 俗稱RAC,屬于函數(shù)式響應(yīng)編程台囱,極大的簡化了邏輯淡溯,方便使用

1、替換代理方法
2簿训、替換KVO
3咱娶、替換NSNotification
4、替換UIControl 的一些響應(yīng)事件
5强品、替換NSTimer
等等膘侮,采用管道式通信機(jī)制,使邏輯更易理解

ReactiveCocoa入門教程:第一部分
ReactiveCocoa入門教程: 第二部分
ReactiveCocoa源碼解析
ReactiveCocoa常用方法
MVVM+RAC 從框架到實戰(zhàn)

RAC使用

使用RAC模擬請求客戶檔案與倉庫檔案

1.先請求客戶檔案數(shù)量择懂,再根據(jù)數(shù)量分批次請求客戶檔案數(shù)據(jù)

2.先請求倉庫檔案數(shù)量喻喳,再根據(jù)數(shù)量分批次請求倉庫檔案數(shù)據(jù)

- (void)viewDidLoad

  RACSignal *consumerSignal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {    

        //模擬發(fā)送一次獲取客戶更新數(shù)量的請求
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

            //假如獲取到count 5
            [self requestConsumerDataWith:subscriber];
        });

        return nil;

    }];

    [consumerSignal subscribeNext:^(id  _Nullable x) {

g
       NSLog(@"客戶檔案更新結(jié)束%@",x);
    }];

    RACSignal *warehouseSignal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {

        //模擬發(fā)送一次獲取倉庫更新數(shù)量的請求
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

            //假如獲取到count 5
            [self requestConsumerDataWith:subscriber];
        });

        return nil;

    }];

    [warehouseSignal subscribeNext:^(id  _Nullable x) {

        NSLog(@"倉庫檔案更新結(jié)束%@",x);
    }];

    //連接兩個信號,只有兩個信號都觸發(fā)時困曙,才能刷新UI 或者讓HUD 消失
    [self rac_liftSelector:@selector(updateUIWithR1:r3:) withSignalsFromArray:@[warehouseSignal,consumerSignal]];  

}

- (void)requestConsumerDataWith:(id<RACSubscriber>)subScriber_consumer{

    RACSignal *consumerSignal = nil;

    for (int i = 1; i < 5; i++) {

        RACSignal *single_temp = [[RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {

            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

                [subscriber sendNext:@(i)];

            });

            return nil;

        }]delay:i];

        if (!consumerSignal) {
            consumerSignal = single_temp;
        }else{
            consumerSignal = [consumerSignal combineLatestWith:single_temp];
        }
    }

    [consumerSignal subscribeNext:^(id  _Nullable x) {
        [subScriber_consumer sendNext:@"客戶檔案請求成功1砺住Gァ!"];
    }];
}

- (void)requestWarehouseDataWith:(id<RACSubscriber>)subScriber_warehouse{

    RACSignal *consumerSignal = nil;

    for (int i = 1; i < 5; i++) {

        RACSignal *single_temp = [[RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {

            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

                [subscriber sendNext:@(i)];

            });

            return nil;

        }]delay:i];

        if (!consumerSignal) {

            consumerSignal = single_temp;

        }else{

            consumerSignal = [consumerSignal combineLatestWith:single_temp];

        }
    }

    [consumerSignal subscribeNext:^(id  _Nullable x) {
          [subScriber_warehouse sendNext:@"倉庫檔案請求成功1暮摺v蕖!"];
    }]纲熏;
}

// 更新UI

- (void)updateUIWithR1:(id)data r3:(id)data2{
  
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末妆丘,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子局劲,更是在濱河造成了極大的恐慌勺拣,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鱼填,死亡現(xiàn)場離奇詭異药有,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)苹丸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進(jìn)店門愤惰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人赘理,你說我怎么就攤上這事宦言。” “怎么了商模?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵奠旺,是天一觀的道長。 經(jīng)常有香客問我阻桅,道長凉倚,這世上最難降的妖魔是什么兼都? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任嫂沉,我火速辦了婚禮,結(jié)果婚禮上扮碧,老公的妹妹穿的比我還像新娘趟章。我一直安慰自己,他們只是感情好慎王,可當(dāng)我...
    茶點故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布蚓土。 她就那樣靜靜地躺著,像睡著了一般赖淤。 火紅的嫁衣襯著肌膚如雪蜀漆。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天咱旱,我揣著相機(jī)與錄音确丢,去河邊找鬼绷耍。 笑死,一個胖子當(dāng)著我的面吹牛鲜侥,可吹牛的內(nèi)容都是我干的褂始。 我是一名探鬼主播,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼描函,長吁一口氣:“原來是場噩夢啊……” “哼崎苗!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起舀寓,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤胆数,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后互墓,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體幅慌,經(jīng)...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年轰豆,在試婚紗的時候發(fā)現(xiàn)自己被綠了胰伍。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,569評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡酸休,死狀恐怖骂租,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情斑司,我是刑警寧澤渗饮,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站宿刮,受9級特大地震影響互站,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜僵缺,卻給世界環(huán)境...
    茶點故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一胡桃、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧磕潮,春花似錦翠胰、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至膏潮,卻和暖如春锻狗,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工轻纪, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留脚囊,地道東北人。 一個月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓桐磁,卻偏偏與公主長得像悔耘,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子我擂,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,446評論 2 348

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