目錄:
- 序言
- 一、架構(gòu)的基礎(chǔ)
- 二、架構(gòu)之MVC
- 三笤虫、架構(gòu)之MVP
- 四、架構(gòu)之MVVM
序言:
架構(gòu)其實(shí)是一個(gè)設(shè)計(jì)上的東西祖凫,它可以小到類與類之間的一個(gè)交互琼蚯,也可以大到不同的模塊之間,或者說不同的業(yè)務(wù)部門之間的交互惠况,都可以從架構(gòu)的層面去理解遭庶。
【理解】:iOS 中也有很多架構(gòu)的設(shè)計(jì)理念,比如代理稠屠,它屬于委托設(shè)計(jì)模式峦睡。比如單 例,是一類單個(gè)對(duì)象長(zhǎng)存的設(shè)計(jì)模式权埠,它不需要傳遞任何參數(shù)榨了,就有效的解決了不同 代碼數(shù)據(jù)共享的問題。還有觀察者模式(通知)攘蔽,一般為model層龙屉,對(duì)controller和view 進(jìn)行通知,它不關(guān)心誰去接收满俗,只負(fù)責(zé)發(fā)布信息转捕。比如常用的 MVC 模式作岖,通過數(shù)據(jù)模 型,控制器邏輯五芝,視圖展示痘儡,將應(yīng)用程序進(jìn)行邏輯劃分等。都是一種架構(gòu)設(shè)計(jì)理念枢步, 一種資源有效整合的方式谤辜,方法。我們?nèi)绻麑?duì)架構(gòu)熟悉了价捧,也可以用自己的理解去, 研究出屬于自己的一套架構(gòu)涡戳,方便日后的工作學(xué)習(xí)结蟋。
一、架構(gòu)的基礎(chǔ)
首先渔彰,架構(gòu)的核心是耦合嵌屎,如何處理不同的類和業(yè)務(wù)模塊之間交互方式,讓它們互相影響最小恍涂,就叫做解耦宝惰。耦合度低,不僅可以幫助我們有效的維護(hù)項(xiàng)目代碼再沧,還 可以提高代碼的質(zhì)量尼夺。架構(gòu)的基礎(chǔ),就是對(duì)耦合概念的理解炒瘸。
1淤堵、案例:
假設(shè)常景: 經(jīng)理讓員工去執(zhí)行打印任務(wù)。
具體操作:
設(shè)計(jì)兩個(gè)類來實(shí)現(xiàn)代碼工程顷扩。創(chuàng)建兩個(gè)類一個(gè)是經(jīng)理拐邪,一個(gè)是員工。為了簡(jiǎn)化場(chǎng)景隘截,把兩個(gè)類都變成單例扎阶。員工要執(zhí)行打印任務(wù),內(nèi)含 doPrintJob 方法婶芭,聲明并 實(shí)現(xiàn)且打印日志东臀。員工執(zhí)行完打印任務(wù),需要告訴經(jīng)理犀农,打印任務(wù)完成了啡邑。所以經(jīng)理 內(nèi)含 celebratePrintDone,方法,聲明實(shí)現(xiàn)并輸出日志井赌。到此為止谤逼,經(jīng)理和員工還是兩 個(gè)獨(dú)立的個(gè)體贵扰。
接下來我們要將二者串聯(lián)起來,串聯(lián)起來的方式就是耦合的方式流部。
第一種戚绕,互相耦合(最差)
經(jīng)理是模塊的入口,所以在經(jīng)理類中枝冀,設(shè)計(jì)接口 beginPrinTask.聲明實(shí)現(xiàn)且對(duì) doPrintJob 調(diào)用舞丛,告訴員工開始打印任務(wù),這樣入口就做好了。
在 ViewDidLoad 中調(diào)用 beginPrintTask 方法進(jìn)行啟動(dòng)果漾。當(dāng)員工打印任務(wù)完成時(shí)球切, 需要告知經(jīng)理,則調(diào)用經(jīng)理 celebratePrintDone绒障。如下圖:
第二種吨凑,利用 Delegate 耦合
蘋果使用的都是消息機(jī)制,我要員工去打印户辱,就是給員工發(fā)送一個(gè)消息鸵钝,其實(shí)就是調(diào)用員工打印的方法。
使用代理解耦庐镐,員工不知道經(jīng)理的存在恩商,經(jīng)理一定知道員工的存在,無論是誰必逆,只 要遵守了員工的協(xié)議怠堪,就代表完成了任務(wù)。
當(dāng)經(jīng)理告訴員工打印任務(wù)之后名眉,員工打印任務(wù)完成了研叫,要告知經(jīng)理,卻不知道怎么 去告知經(jīng)理璧针,則需要一個(gè)委托人代替它去告知經(jīng)理任務(wù)完成嚷炉。怎么去做呢?員工需要 和委托人之間有個(gè)協(xié)議,去告訴經(jīng)理 PrintJobDone探橱。
第三種申屹,利用 Notification 耦合
首先,需要生成一個(gè).h 文件隧膏,來定義我們通知的類型,一個(gè)是開始打印哗讥,一個(gè)是打印完 成,比如:
#define Notif_BeginPrintTask @"Notif_BeginPrintTask"
#define Notif_PrintTaskDone @"Notif_PrintTaskDone"
經(jīng)理需要告訴外界我有一個(gè)打印的需求胞枕,則需要在beginPrintT ask方法中POST消息杆煞, 員工呢,去監(jiān)聽這個(gè)信息,如果對(duì)這個(gè)需求信息感興趣的話决乎,就去執(zhí)行doPrintJob方法队询。 打印完成后,需要告訴外界构诚,打印完畢蚌斩。外界需要監(jiān)聽一下完成這個(gè)消息。
我們其實(shí)都沒有把耦合消滅掉范嘱,是把耦合全都移到了一個(gè).h 文件中送膳,將耦合變成 了一個(gè)信號(hào),一個(gè)事件丑蛤。
二叠聋、架構(gòu)之MVC
1、 介紹
MVC 是蘋果原生推薦的架構(gòu)方式受裹,也是行內(nèi)經(jīng)典的架構(gòu)模式碌补,幾乎所 有的邏輯處理都離不開這三個(gè)類。
- M (Model) 代表數(shù)據(jù)部分
- V (View) 代表視圖展示
- C (Controller) 代表控制器
當(dāng)然我們也可以對(duì)它們進(jìn)行細(xì)分名斟,Controller 可以分更多的模塊,View 也可以分更多個(gè)子 View 進(jìn)行控制魄眉,Model 也可以分多個(gè) Model 類型砰盐。
2、講解
通過上圖坑律,我們知道有三個(gè)角色岩梳,Controller、View晃择、Model冀值,三者之間交互就 決定了架構(gòu)的耦合程度和便于維護(hù)的程度。
Controller 有兩個(gè)紅色的箭頭分別指向 View 和 Model宫屠。
- Controller->View
就代表 Controller 可以控制 View 的渲染列疗,這樣的一個(gè)命令。
- Controller->Molde
代表 Controller 可以修改 Model浪蹂。
另外抵栈, View 也有兩個(gè)綠色的箭頭,分別指向 Controller 和 Model坤次。
- View->Controller
代表 View 這邊采集到的用戶數(shù)據(jù)古劲,用戶事件,會(huì)反饋給 Controller 做進(jìn)一步的處理缰猴。
- View->Model
代表 View 可以讀取 Model,進(jìn)一步展示自己的界面产艾。
從這個(gè)圖形中我們可以指導(dǎo) Controller 是我們的中心控制器部分,所有的關(guān)鍵業(yè) 務(wù)邏輯部分都是從 Controller 部分發(fā)生的。這就是 MVC 這個(gè)架構(gòu)為什莫這么方便維護(hù) 的原因闷堡。是因?yàn)槲覀儗⒅饕鸟詈喜糠职臁⒅匾倪壿嫴糠侄挤诺搅?Controller 當(dāng)中。
3缚窿、案例
我們新建一個(gè) MVCController 類,在 ViewController 中 present 出來,設(shè)置dispatch_after 2 秒之后展示出來棘幸。我們?cè)诮⒁粋€(gè) MVCView,創(chuàng)建一個(gè) Model 因?yàn)?model 執(zhí)行一個(gè)打印的操作,所以我們建立一個(gè) Paper 作為 model倦零。
這樣我們就有個(gè) MVC 三個(gè)對(duì)象误续,接下來就來執(zhí)行我們的交互。在 MVCController 中 ViewDidLoad 中我們會(huì)執(zhí)行一個(gè)打印的任務(wù)扫茅。生成 printPapaer 這樣一個(gè)函數(shù)蹋嵌。接下來我們要是這三個(gè)角色串聯(lián)起來,首先要 先生成我們 View/Model 的對(duì)象 myView 和 paper葫隙。因?yàn)?MVCController 是 控制 View栽烂、Model 兩個(gè)對(duì)象的,所以我們需要兩個(gè)引用恋脚。
另外腺办,我們回到 MVCView 當(dāng)中,view 需要一個(gè)操作 printOnView: (Paper*)paper 把這個(gè) View 展示出去,需要傳入我們的 Model糟描。View 當(dāng)中有 一個(gè)事件可以告知到我們的 MVCController怀喉,所以在定一個(gè)協(xié)議 MVCViewDelegate,傳給 MVCController 一個(gè)事件 onPrintBtnClick,聲明一 個(gè)代理對(duì)象船响。
接下來躬拢,我們定義我們的 Paper,它有一個(gè) content 屬性,是一個(gè)純 Model 沒有業(yè)務(wù)邏輯见间。
回到控制器的部分聊闯,在 printPapaer 部分,我們需要告訴 View 去打印 這樣一個(gè) Paper米诉。在 ViewDidLoad 進(jìn)行 myView /paper 初始化操作菱蔬,并在 其中實(shí)現(xiàn)一個(gè) MVCViewDelegate,實(shí)現(xiàn) onPrintBtnClick 方法。
執(zhí)行我們的 printPaper史侣,其實(shí)就是告訴我們的 View 去打印汗销。 [self.myView printOnView:self.paper]; 隨意設(shè)置一個(gè) content 的值,在 printOnView:(Paper*)paper 方法中打印一個(gè)日志抵窒, NSLog(@"printing
paper content:%@",paper.content);
結(jié)論①
測(cè)試會(huì)打印出來 Line0,這樣我們就完成了弛针,Controller 去控制 View 去
展示 Model 內(nèi)容這樣一個(gè)流程。
接下來是另一個(gè)流程李皇,view 采集到用戶的事件削茁,告訴 Controller 去做
一下處理宙枷。
在 View 中我們要生成一個(gè) btnPrint 去采集用戶事件,在 View,init 中 初始化這個(gè) btnPrint,給 View 增加一個(gè)背景色茧跋,淡灰色.設(shè)置 btnPrint 的屬 性 frame慰丛、title、添加點(diǎn)擊事件 onPrintClick瘾杭。
在采集到用戶事件之后我們需要傳遞給我們的 Controller,在 Controller中才能做處理決定下一步該怎么做诅病。
執(zhí)行到上一步就可以將,事件傳遞給我們的 Controller粥烁,Controller 將進(jìn) 一步改變我們的 Model,之后我們?cè)趯⒅噶畎l(fā)送給 View,讓 View 去渲染新的 Model 對(duì)象贤笆。如下圖 Controller 遵守代理方法的實(shí)現(xiàn):
結(jié)論②
這就是另一個(gè)數(shù)據(jù)流向的一個(gè)流程,在我們的 View 采集到數(shù)據(jù)之后讨阻, 將數(shù)據(jù)拋給我們的 Controller, Controller 修改數(shù)據(jù)芥永,然后將新的數(shù)據(jù), 拋給 View 去展示钝吮。
4埋涧、總結(jié)
- 流程 1 、Controller 初始化 發(fā)指令給 View 去展示我們的 model
- 流程 2 奇瘦、View 通過用戶采集到事件之后將棘催,將時(shí)間發(fā)送給 Controller,
Controller 采集到做進(jìn)一步的處理之后,刷新我們的 View耳标。
三醇坝、架構(gòu)之MVP
1、 基本介紹
架構(gòu)有很多麻捻,我們最好是在 MVC 的基礎(chǔ)上去學(xué)習(xí)纲仍,好多架構(gòu)都是 MVC 的變種呀袱。MVP 也不例外贸毕,是 MVC 的一個(gè)變種。
上圖列舉了 MVC 和 MVP夜赵,方便大家可以比較一下二者之間的差異明棍。 在之前,我們介紹MVC的時(shí)候寇僧,通過Controller來控制View和Model, 而且 View 可以獲取到 Moedl 并進(jìn)行自己的更新摊腋。
大家可以看一下左邊的流程圖,User Interaction(用戶事件)之后嘁傀, 是向它傳遞給 Controller, Controller 改變 Model,Model 之后就會(huì)反應(yīng)到 View 上去兴蒸。MVC 示意圖有一個(gè)很重要的點(diǎn)是 MVC 三個(gè)角色是互相知 道,互相引用细办。像 View 是知道 Model 的存在的橙凳。
那么,到 MVP 的時(shí)候,我們會(huì)發(fā)現(xiàn) Controlller 消失了岛啸,多出一個(gè) Presenter钓觉。大家可以將 Presenter 理解成 Controlller 一個(gè)類似的概念。 只不過數(shù)據(jù)流流向有些變化坚踩,所以給它我了一個(gè)新的名字叫 Presenter荡灾。 但是總的來說,它也屬于一個(gè)控制中心瞬铸。
從右邊 MVP 中批幌,我們可以看到和 MVC 不一樣的地方,View 和 Model 之間赴捞,是互相不存在的逼裆,不存在引用,不存在依賴赦政,所有的耦合 到放在 Presenter 當(dāng)中胜宇。
回到我們打印的例子來說,Presenter 會(huì)控制 View 執(zhí)行打印任務(wù)恢着, View 并不直接持有 Model 的引用桐愉。Presenter 會(huì)以另外一種形式展示給 View,View 將其打印在自己的 UI 界面上掰派。
2从诲、 案例講解
打開 Xcode,我們新建一個(gè)目錄 MVP,創(chuàng)建一個(gè) MVPViewController靡羡,因 為 MVPViewController 是蘋果 iOS 編程中最基礎(chǔ)的單元系洛,是必須要有的, 所以我們還是進(jìn)一步保留略步。不過和之前不同的是描扯,我們不會(huì)在其中在放 入很多邏輯業(yè)務(wù)的代碼。我們?cè)偕梢粋€(gè) Presenter趟薄,生成我們 View 的對(duì)象 MVPView 和 MVPModel绽诚。
接下來,我們?cè)?MVPViewController 當(dāng)中將三個(gè)角色進(jìn)行關(guān)聯(lián)杭煎,在 ViewDidLoad 當(dāng)中進(jìn)行處理恩够,我們需要導(dǎo)入三個(gè)頭文件,在 interface 當(dāng)中聲明羡铲。因?yàn)橐?MVPViewController 當(dāng)中蜂桶,對(duì)三個(gè)角色進(jìn)行串聯(lián), 所以我們將三個(gè)對(duì)象的生成也切,都放在 MVPViewController.m 文件中扑媚。
聲明圖中三個(gè)對(duì)象妥曲,并進(jìn)行初始化,如圖下:
MVP 當(dāng)中的 Model,我們還是采取之前的例子,打印 Paper 一樣钦购, 如下圖:
View 的話他有一個(gè)函數(shù) printOnView 方法檐盟,實(shí)現(xiàn)。Presenter 的話,它有一個(gè)方法押桃,是我們業(yè)務(wù)邏輯的入口葵萎,我們打印的一個(gè)業(yè)務(wù)功能 的入口,printTask 并實(shí)現(xiàn)。
前面已經(jīng)介紹唱凯,所有的耦合都放在 Presenter 里羡忘,Presenter 是需 要知道 View 和 Model 存在的。這里我們將它進(jìn)行一下聲明磕昼。有個(gè) View 和 Model 我們就需要把他們進(jìn)行展示出來卷雕。printTask 就是調(diào)用 View,并 把 Model 的內(nèi)容傳給它票从。
因?yàn)?View 打印的話漫雕,并不知道 Model 的存在,所以我們的內(nèi)容需 要手動(dòng)的傳過來峰鄙。跟 MVC 不同的就是并不是直接的將 Model 傳進(jìn)來浸间, 而是將一個(gè) string 傳進(jìn)來。因?yàn)?view 并不知道 model 的存在吟榴,是不能 引用 Model 這個(gè)類的魁蒜。
接下來我們?cè)?MVPView 當(dāng)中把它實(shí)現(xiàn)雌芽,通過一個(gè) Label 把 content 展示出來俄认,我們?cè)?init 當(dāng)中對(duì)其進(jìn)行初始化。
如下圖:
這樣的話撼嗓,View 就基本完成了它的工作狭瞎,model 就完成了它的定義细移。 接下來所有的業(yè)務(wù)邏輯處理都交給 Presenter 來進(jìn)行處理。
在 Presenter 當(dāng)中脚作,需要將 content 傳遞給 View葫哗。如下圖缔刹,這樣我們 就完成了一個(gè)流程球涛。就是我們啟動(dòng)時(shí)的一個(gè)業(yè)務(wù)流程的一個(gè)入口,我們 通過 Presenter 來校镐,來指定我們的 View 來打印這一個(gè)內(nèi)容亿扁。這是我們的 第一步。
當(dāng)然鸟廓,我們也需要在 ViewController 當(dāng)中从祝,對(duì) MVPViewController 進(jìn)行實(shí)現(xiàn)襟己。showMVP 兩秒之后進(jìn)行展示。并在 MVPViewController 當(dāng)中 對(duì) Model 進(jìn)行賦值牍陌。
測(cè)試一下擎浴,并沒打印,原因是我們?nèi)叩年P(guān)系還沒建立好毒涧,我們把他 們進(jìn)一步建立贮预。Presenter 需要指導(dǎo) View 的存在,我們把聲明的兩個(gè)屬 性 view,和 model 暴露在外部契讲。這樣就可以給 MVPViewController 賦值 了仿吞。
我們看到了 Presenter 是處理三者耦合的一個(gè)類,這樣我們?cè)诰S護(hù)我 們的項(xiàng)目捡偏,維護(hù)我們的代碼耦合的時(shí)候唤冈,就會(huì)變的更加的方便。
Presenter 的話银伟,它有一個(gè)業(yè)務(wù)邏輯的入口叫 printTask你虹,在 MVPViewController 當(dāng)中進(jìn)行調(diào)用。打一個(gè)斷點(diǎn)進(jìn)行檢測(cè)彤避,打印成功售葡。 說明我們的流程是成功的。
接下來我們做另一個(gè)工作忠藤,就是之前跟 MVC 一樣的挟伙,在 View 上的按 鈕,響應(yīng)一個(gè)點(diǎn)擊事件模孩。通知我們的 Presenter 去執(zhí)行這樣一個(gè)操作尖阔, 這個(gè)操作和我們之前 MVC 的比較一致。這里就不做過多解釋了榨咐。利用代 理介却。
四、架構(gòu)之MVVM
1块茁、 基本介紹
MVVM 架構(gòu)也是 MVC 架構(gòu)演化出來的齿坷,大家可以看到圖中有三個(gè)角色, View/ViewModel/Model,和 MVC 相比数焊,Controller 沒有了永淌,多了一個(gè) ViewModel。
我們可以直觀的想到 ViewModel 是不是取代了 Controller 的角色佩耳,它不 但取代了 Controller 也多了一些不一樣的地方遂蛀。我們可以從它的名字推斷出, 它并不全是一個(gè)業(yè)務(wù)邏輯中一個(gè)類干厚,它同時(shí)和 View 和 Model 是相關(guān)聯(lián)的李滴, 這也是 MVVM 主要的特征之一螃宙。View 和 ViewModel 是雙向綁定的。
什莫意思呢?比如說所坯,我們 View 上有一個(gè) label谆扎,label 上它的 text 對(duì)應(yīng) 到 Model 里面的一個(gè) name 的 string 字符段。我們的 ViewModel 它也會(huì)有一個(gè) next 的 string 字符段芹助。如果 nextString 發(fā)生改變的話燕酷,nameLabel 它對(duì)應(yīng)的 text 值會(huì)自動(dòng)的更新。同理周瞎,若果 View 上的一個(gè) btn 產(chǎn)生事件的話苗缩,viewModel 能夠自動(dòng)的監(jiān)聽到,這里是一個(gè)雙向的過程声诸。iOS 上面有很多方法可以實(shí)現(xiàn)酱讶, 可以用 RAC 去做,也可以用 KVO 來做彼乌,下面的案例會(huì)采用 KVO 方式來做泻肯,理 解這種雙向綁定。
ViewModel 同時(shí)也跟 Model 發(fā)生一個(gè)關(guān)系慰照,ViewModel 可以改變 Model 值灶挟, 同時(shí),在 Model 發(fā)生改變的時(shí)候毒租,它可以將 Model 最新的值讀取到稚铣。并將它反 應(yīng)到 View 上。
2墅垮、 案例(打印)
這里我們新建一個(gè)目錄 MVVM惕医,我們新建一個(gè) MVVMController,在 MVVM 主要角 色里并沒有 Controller算色,它相當(dāng)于一個(gè)空殼的作用抬伺。我們需要簡(jiǎn)歷 MVVM 三個(gè)角色, MVVMView灾梦、MVVMPaper/MVVMViewModel,這就有個(gè) MVVM 的三個(gè)角色峡钓。
接下來,我們對(duì)三個(gè)角色進(jìn)行初始化若河,我們將三個(gè)角色的頭文件能岩,導(dǎo)入 MVVMController,生成三個(gè)實(shí)例牡肉,分別為paper/mvvmView/viewModel,并進(jìn)行實(shí)例化捧灰。
對(duì)于 MVVMPaper 我們好跟之前一樣淆九,有一個(gè) NSString 屬性 content,在 MVVMController 給它初始化內(nèi)容统锤。MVVMView 它有一個(gè) label 去展示 paper 的 content毛俏。 在 init 方法中對(duì)它進(jìn)行初始化。
接下來是我們的 MVVMViewModel,之前我們提到了它和 View 之間有一個(gè)相互綁定 的關(guān)系饲窿,所以我們?cè)?MVVMViewModel 的頭文件中生成一個(gè) NSString 的 contentStr煌寇。 這個(gè) contentStr 是用來和 View 進(jìn)行雙向綁定作用的。
接下來我們需要在 MVVMViewModel 當(dāng)中逾雄,建立一個(gè)雙向綁定的關(guān)系阀溶,這個(gè)綁定 也是 MVVM 架構(gòu)一個(gè)核心的地方。這里將采用 KVO 來實(shí)現(xiàn)鸦泳。
KVO 我們將采用 FaceBook 中一個(gè)著名的庫(kù) FBKVO银锻,將它導(dǎo)入進(jìn)來,大家可以去 網(wǎng)上搜索一下做鹰,這個(gè)庫(kù)非常的有名和實(shí)用击纬。其實(shí)它就是非常簡(jiǎn)單的告訴我們?nèi)绾问褂?KVO,我們導(dǎo)入頭文件 FBKVOController.h钾麸,關(guān)系應(yīng)該在 MVVMView 中去建立更振。
MVVMView 需要和 MVVMViewModel 綁定,則我們需要把 MVVMViewModel 的頭文件 導(dǎo)進(jìn)來饭尝。在 MVVMView 當(dāng)中肯腕,它需要一個(gè) setWithViewModel:(MVVMViewModel*) vm,在這個(gè)方法里我們建立一個(gè)雙向的綁定。
這樣钥平,我們就完成了一個(gè) View->ViewModel 的綁定实撒,每次 ViewModel 的 contentStr 發(fā)生 改變的時(shí)候,這樣_lbContent 的值就會(huì)自動(dòng)的賦過去涉瘾。
這樣奈惑,有什莫好處呢?一旦我們的 View 建立完成之后,我們展示的邏輯就會(huì)跟我 們 Model 的改變完全隔離開來睡汹。不用操心 View 的值是怎么顯示的肴甸,我們只要把注意力和重點(diǎn)關(guān)注在業(yè)務(wù)邏輯上,怎么去改變我們的 Model囚巴。
下面我們?nèi)?MVVMController 里面去調(diào)用一下 setWithViewModel:如下圖:
這樣原在,我們就可以監(jiān)聽到_paper.content = @"line 0";這樣一個(gè)值。
接下來我們實(shí)現(xiàn)第二個(gè)綁定彤叉,我們的 ViewModel 需要有一個(gè)事件庶柿。我們?cè)?MVVMView 中添加一個(gè) Btn,初始化,接下來是我們一個(gè)事件的處理秽浇。事件的處理非常 簡(jiǎn)單浮庐,因?yàn)槲覀円呀?jīng)有一個(gè) ViewModel 的一個(gè)引用了,我們只要將事件傳遞過去。
所以审残,ViewModel 需要一個(gè)時(shí)間的回調(diào),我們?cè)?ViewModel 里聲明一個(gè)方法梭域, onPrintClick 并實(shí)現(xiàn),在 MVVMView 中設(shè)置 ViewModel 的引用搅轿,并關(guān)聯(lián)病涨。 在 MVVMView 中調(diào)用 onPrintClick 方法,這樣就將時(shí)間傳遞給我們的 ViewModel璧坟。
Model 的話既穆,接下來我們只要,改變 Content 就可以改變這樣一個(gè)內(nèi)容雀鹃。因?yàn)槲覀?的 ViewModel 還要跟我們的 Model 發(fā)生一個(gè)關(guān)聯(lián)幻工,所以在 ViewModel 里面將 MVVMPaper 導(dǎo)入進(jìn)來,并聲明 model黎茎。我們還需要將 paper 傳進(jìn)來会钝,所以如下圖:
并實(shí)現(xiàn),賦值的時(shí)候工三,我們需要將當(dāng)前的 contentStr 進(jìn)行賦值迁酸。如下圖:
因?yàn)椋拔覀円呀?jīng)建立過綁定俭正,改變 contentStr 的值的時(shí)候奸鬓,View 上就能夠自動(dòng) 的監(jiān)聽到這個(gè)值的變化,能夠在 label 上進(jìn)行一個(gè)新的值的展示掸读。所以實(shí)現(xiàn)下面的方法: 如下圖:
在 MVVMController 里串远,我們需要將 model 傳過去,如下圖:
與 ViewController 進(jìn)行處理儿惫,Com +R 運(yùn)行測(cè)試一下澡罚。
未完待續(xù)