iOS架構設計之MVC

一、MVC闡述

1.MVC(Model、View污淋、Controller),即模型骑疆、視圖田篇、控制器;
  • Model:
    模型對象封裝了應用程序的數(shù)據(jù)箍铭,并定義操控和處理該數(shù)據(jù)的邏輯和運算泊柬。例如,模型對象可能是表示商品數(shù)據(jù) list诈火。用戶在視圖層中所進行的創(chuàng)建或修改數(shù)據(jù)的操作兽赁,通過控制器對象傳達出去,最終會創(chuàng)建或更新模型對象柄瑰。模型對象更改時(例如通過網(wǎng)絡連接接收到新數(shù)據(jù)),它通知控制器對象剪况,控制器對象更新相應的視圖對象教沾。

  • View:
    視圖對象是應用程序中用戶可以看見的對象。視圖對象知道如何將自己繪制出來译断,可能對用戶的操作作出響應授翻。視圖對象的主要目的就是顯示來自應用程序模型對象的數(shù)據(jù),并使該數(shù)據(jù)可被編輯孙咪。盡管如此堪唐,在 MVC 應用程序中,視圖對象通常與模型對象分離翎蹈。

  • Controller:
    在應用程序的一個或多個視圖對象和一個或多個模型對象之間淮菠,控制器對象充當媒介』缈埃控制器對象因此是同步管道程序合陵,通過它,視圖對象了解模型對象的更改澄阳,反之亦然拥知。控制器對象還可以為應用程序執(zhí)行設置和協(xié)調任務碎赢,并管理其他對象的生命周期低剔。
    控制器對象解釋在視圖對象中進行的用戶操作,并將新的或更改過的數(shù)據(jù)傳達給模型對象肮塞。模型對象更改時襟齿,一個控制器對象會將新的模型數(shù)據(jù)傳達給視圖對象,以便視圖對象可以顯示它枕赵。

2.實例描述
  • 比如在iOS程序中蕊唐,視圖、按鈕烁设、彈框等都對應View替梨,承載數(shù)據(jù)特征或數(shù)據(jù)處理邏輯的Object對應Model钓试,通常一個頁面下會用到多個View和Model,如根據(jù)條件展示不同的彈框副瀑,這個時候就需要一個管理者來管理他們弓熏,也就是需要一個控制器,那么iOS中的ViewController就對應上面所說的Controller糠睡。

就比如畫畫一樣挽鞠,有模特、畫師狈孔、畫板

  • 需要展現(xiàn)的是模特的身材信认、樣貌、氣質等特征均抽,那么模特就對應Model嫁赏,他封裝了要展示的數(shù)據(jù);

  • 畫板需要將模特的身材油挥、樣貌潦蝇、氣質等特征呈現(xiàn)出來,對應View深寥;

  • 而畫師則負責在兩者之間做傳遞攘乒,畫師需要將自己所看到的模特的樣子畫在畫板上,如果模特換了個姿勢惋鹅,換了套衣服则酝,會影響畫師去調整或更換畫板,同時畫板的成像效果也會影響到畫師來通知模特做些調整闰集,比如保持微笑等,堤魁,畫師對應Controller

3.MVC 的幾個明顯的特征和體現(xiàn):
  • View上展示什么東西取決于Model
  • 只要 Model 數(shù)據(jù)改了,View 的顯示狀態(tài)會跟著更改
  • Controller 負責初始化 Model和VIew返十,并將 Model 傳遞給 View 去解析展示
4.簡單的 MVC
  • 控制器加載模型數(shù)據(jù)并將數(shù)據(jù)轉換為數(shù)據(jù)模型妥泉。
  • 控制器創(chuàng)建視圖控件,并將模型數(shù)據(jù)傳遞給視圖控件
MVC結構圖

二洞坑、iOS中的標準MVC

1.比如iOS中的如下例子
  • 創(chuàng)建一個TestView
#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface TestView : UIView

@property (nonatomic, strong) UILabel *nameLb;

@end

NS_ASSUME_NONNULL_END
#import "TestView.h"

@implementation TestView

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self addSubview:self.nameLb];
    }
    return self;
}

- (UILabel*)nameLb
{
    if (!_nameLb) {
        _nameLb = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 80, 30)];
        _nameLb.center = self.center;
        _nameLb.textAlignment = NSTextAlignmentCenter;
    }
    return _nameLb;
}

/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
    // Drawing code
}
*/

@end
  • 創(chuàng)建一個Model
#import <Foundation/Foundation.h>

@interface ZYModel : NSObject

@property (nonatomic, copy) NSString *name;

@end
#import "ZYModel.h"

@implementation ZYModel

@end
  • 創(chuàng)建一個Controller
#import <UIKit/UIKit.h>

@interface ViewController : UIViewController


@end
#import "ViewController.h"
#import "ZYModel.h"
#import "TestView.h"

@interface ViewController ()

@property (nonatomic, strong) ZYModel *zyModel;
@property (nonatomic, strong) TestView *testView;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self loadData];
    [self initTestView];
    
    
}

- (void)loadData
{
    self.zyModel = [[ZYModel alloc] init];
    self.zyModel.name = @"趙揚揚";
}

- (void)initTestView
{
    self.testView = [[TestView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
    self.testView.center =  self.view.center;
    self.testView.nameLb.text = self.zyModel.name;
    [self.view addSubview:self.testView];
}

@end

由上圖的例子可以看出盲链,控制器加載模型數(shù)據(jù)并將數(shù)據(jù)轉換為數(shù)據(jù)模型〕僭樱控制器創(chuàng)建視圖控件刽沾,并將模型數(shù)據(jù)傳遞給視圖控件

但在實際應用過程中,由于不可避免的交互排拷,數(shù)據(jù)和界面都會出現(xiàn)更新侧漓,因此就會產(chǎn)生通信,在iOS中监氢,MVC模式的通信關系如下圖所示


iOSMVC
  • Model 和 View 永遠不能相互通信布蔗,只能通過 Controller 傳遞藤违。

  • Controller 可以直接與 Model 對話(讀寫調用 Model),Model 通過 Notification 和 KVO 等機制與 Controller 間接通信纵揍。

  • Controller 可以直接與 View 對話顿乒,通過 outlet,直接操作 View泽谨,outlet 直接對應到 View 中的控件璧榄,View 通過 action 向 Controller 報告事件的發(fā)生(如用戶 Touch 我了)。Controller 是 View 的直接數(shù)據(jù)源(數(shù)據(jù)很可能是 Controller 從 Model 中取得并經(jīng)過加工了)吧雹。Controller 是 View 的代理(delegate)骨杂,以同步 View 與 Controller。

比如在上面的iOS例子中雄卷,如果ZYModel中的name屬性改變了搓蚪,由趙揚揚變成了揚揚,那么TestView上就不能再展示為趙揚揚了龙亲,要變成揚揚陕凹,這個流程如下:ZYModel通過一種方式告知ViewCotroller我的name改變了悍抑,然后由ViewCotroller去告知TestView去更新展示鳄炉,同樣的道理,如果是TestView由于用戶的交互要改變ZYModel的name搜骡,也是通過ViewCotroller去傳達拂盯。如下圖

iOS標準MVC通信流程

三、MVC變種

在上面的例子中记靡,ZYModel只有一個屬性谈竿,TestView也只有一個nameLb屬性,控制器傳值的時候是將ZYModel的對象數(shù)據(jù)傳給TestView的對應屬性或控件摸吠,但如果ZYModel和TestView都擁有多個屬性空凸,那么按照上面所說的模式則只能一一對應傳值,而且TestView需要將它需要更新的屬性全部暴露出來寸痢!

@interface TestView : UIView

@property (nonatomic, strong) UILabel *nameLb;
@property (nonatomic, strong) UILabel *ageLb;
@property (nonatomic, strong) UILabel *sexLb;

@end
@interface ZYModel : NSObject

@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *age;
@property (nonatomic, copy) NSString *sex;

@end

在VIewController中將這些傳值

self.testView.nameLb.text = self.zyModel.name;
self.testView.ageLb.text = self.zyModel.age;
self.testView.sexLb.text = self.zyModel.sex;

由上面的例子可以看出呀洲,如果屬性很多、模型也不知一個啼止,這樣一來Controller中的代碼會非常臃腫道逗,所以通常我們開發(fā)中會做一些改動,讓View依賴于Model献烦,將View內部的細節(jié)封裝起來滓窍!如下圖所示

iOS中MVC的變種

相對于標準的MVC,變種過的MVC中由于View依賴于Model巩那,所以View的獨立性和可復用性不如標準MVC中的View高

但變種MVC的控制器代碼更精簡一些吏夯,View的封裝性更好一些此蜈。

總結

在實際開發(fā)中,如果采用MVC模式锦亦,往往會造成控制器比較臃腫舶替,因為往往一個控制器需要承載和管理多個View和Model,再者杠园,這幾層之間耦合比較嚴重顾瞪,不利于大型項目的維護,其靈活性也比較差抛蚁。在實際應用中陈醒,應盡量給控制器瘦身、抽離業(yè)務邏輯瞧甩。以免代碼臃腫钉跷、耦合嚴重!

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末肚逸,一起剝皮案震驚了整個濱河市爷辙,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌朦促,老刑警劉巖膝晾,帶你破解...
    沈念sama閱讀 219,490評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異务冕,居然都是意外死亡血当,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評論 3 395
  • 文/潘曉璐 我一進店門禀忆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來臊旭,“玉大人,你說我怎么就攤上這事箩退±胙” “怎么了?”我有些...
    開封第一講書人閱讀 165,830評論 0 356
  • 文/不壞的土叔 我叫張陵戴涝,是天一觀的道長滋戳。 經(jīng)常有香客問我,道長喊括,這世上最難降的妖魔是什么胧瓜? 我笑而不...
    開封第一講書人閱讀 58,957評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮郑什,結果婚禮上府喳,老公的妹妹穿的比我還像新娘。我一直安慰自己蘑拯,他們只是感情好钝满,可當我...
    茶點故事閱讀 67,974評論 6 393
  • 文/花漫 我一把揭開白布兜粘。 她就那樣靜靜地躺著,像睡著了一般弯蚜。 火紅的嫁衣襯著肌膚如雪孔轴。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,754評論 1 307
  • 那天碎捺,我揣著相機與錄音路鹰,去河邊找鬼。 笑死收厨,一個胖子當著我的面吹牛晋柱,可吹牛的內容都是我干的。 我是一名探鬼主播诵叁,決...
    沈念sama閱讀 40,464評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼雁竞,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了拧额?” 一聲冷哼從身側響起碑诉,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎侥锦,沒想到半個月后进栽,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,847評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡捎拯,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,995評論 3 338
  • 正文 我和宋清朗相戀三年泪幌,在試婚紗的時候發(fā)現(xiàn)自己被綠了盲厌。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片署照。...
    茶點故事閱讀 40,137評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖吗浩,靈堂內的尸體忽然破棺而出建芙,到底是詐尸還是另有隱情,我是刑警寧澤懂扼,帶...
    沈念sama閱讀 35,819評論 5 346
  • 正文 年R本政府宣布禁荸,位于F島的核電站,受9級特大地震影響阀湿,放射性物質發(fā)生泄漏赶熟。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,482評論 3 331
  • 文/蒙蒙 一陷嘴、第九天 我趴在偏房一處隱蔽的房頂上張望映砖。 院中可真熱鬧,春花似錦灾挨、人聲如沸邑退。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽地技。三九已至蜈七,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間莫矗,已是汗流浹背飒硅。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留作谚,地道東北人狡相。 一個月前我還...
    沈念sama閱讀 48,409評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像食磕,于是被迫代替她去往敵國和親尽棕。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,086評論 2 355

推薦閱讀更多精彩內容