一疚沐、MVC模式?
MVC概念
MVC把軟件系統(tǒng)分為三個(gè)部分:Model,View潮模,Controller亮蛔。分別對(duì)應(yīng)的就是模型-視圖-控制器
Model:封裝了應(yīng)用程序的數(shù)據(jù),并定義操控和處理該數(shù)據(jù)的邏輯和運(yùn)算
View:是應(yīng)用程序中用戶可以看見(jiàn)的對(duì)象
Controller:充當(dāng)Model與View之間的媒介擎厢。View中進(jìn)行的用戶操作可以通過(guò)Controller傳達(dá)給Model究流,Controller也可將Model傳遞給View,以便View可以顯示它
Model與View之間不能相互通信
MVC之間的交流模式
圖中有幾條線把這三部分劃分開(kāi)动遭,有黃線芬探,虛線,和白色的實(shí)線厘惦。我們把它們想象成路標(biāo)
你可以看到偷仿,在M和V之間有兩條黃線,這表示什么呢宵蕉?它意味著你不能 穿越這黃線酝静,任何一個(gè)方向都不行,即M和V完全分離
在圖的上部国裳,你可以看到白色的虛線形入,它意味著你可以自由的穿越它,只要是安全的
那白色的實(shí)線呢缝左?它代表你可以穿越亿遂,但你必須要買票,或者交點(diǎn)過(guò)路費(fèi)
Controller與Model
首先渺杉,我們來(lái)看C和M之間的綠色箭頭蛇数,這箭頭的方向就代表著“發(fā)起對(duì)話”的方向
也就是說(shuō),發(fā)起對(duì)話的是C是越,而做出回答的是M耳舅。C可以問(wèn)M各種各樣的問(wèn)題,但M只是回答C的問(wèn)題或要求,它不可以主動(dòng)的向C要求什么
還記得虛線是暢通無(wú)阻的意思吧浦徊,所以馏予,C知道M的所有的事情
如果用代碼來(lái)說(shuō)明這件事情,就是說(shuō)盔性,C可以導(dǎo)入M的頭文件或是M的接口(API)霞丧。因?yàn)镃可以通過(guò)M的API,所以它就可以肆無(wú)忌憚的向M要求這要求那了
Controller與View
我們?cè)賮?lái)看看另外的一個(gè)綠色箭頭冕香,它是在C和V之間蛹尝,和前一個(gè)綠色箭頭的意義一樣,它代表C可以直接地向V進(jìn)行交流
你可以想想悉尾,C要把V放到屏幕上突那,并設(shè)置V的屬性,告訴它們什么時(shí)候從屏幕上消失构眯,把它們分成組等等愕难。
如果C不能自由的向V發(fā)號(hào)施令的話,程序的顯示將會(huì)多么的困難鸵赖。所以务漩,C可以毫無(wú)限制地向V說(shuō)話。
可能你已經(jīng)注意到了它褪,這個(gè)箭頭上還有outlet(輸出口),outlet可以看作是從C指向V的指針翘悉,它在C中被定義
outlet給我們提供了很大的方便茫打,它使我們?cè)贑的內(nèi)部就可以輕松準(zhǔn)確地向V施令
C可以擁有很多的outlet,可以不止一個(gè)妖混,這也使它可以更高效的和V進(jìn)行交流
Model與View
那M和V之間可以交流么老赤?還記得黃線的意思么?完全不可以通過(guò)制市,所以我們是不允許M和V進(jìn)行交流的
這是因?yàn)槲覀儾幌M@三部分之間有過(guò)多的交流
你想想抬旺,假如V在顯示時(shí)出現(xiàn)了問(wèn)題,比如有一個(gè)圖形沒(méi)有顯示出來(lái)祥楣,我們就要去查找錯(cuò)誤
因?yàn)镃可以和V交流开财,M也可以和V交流的話,我們就要去檢查兩個(gè)部分
相反的误褪,只有C可以和V交流的話责鳍,在出錯(cuò)時(shí),我們就只需要去C那里查找原因兽间,這樣查找錯(cuò)誤不就很是簡(jiǎn)單了么历葛?
所以,我們不允許M和V之間有直接的聯(lián)系嘀略,這也是在它們兩之間有兩根黃線的原因
總結(jié)
(1)Model和View永遠(yuǎn)不能相互通信恤溶,只能通過(guò)Controller傳遞乓诽。
(2)Controller可以直接與Model對(duì)話(讀寫(xiě)調(diào)用Model),Model通過(guò)Notification和KVO機(jī)制與Controller間接通信咒程。
(3)Controller可以直接與View對(duì)話问裕,通過(guò)outlet,直接操作View
outlet直接對(duì)應(yīng)到View中的控件孵坚,View通過(guò)action向Controller報(bào)告事件的發(fā)生(如用戶Touch我了)
Controller是View的直接數(shù)據(jù)源(數(shù)據(jù)很可能是Controller從Model中取得并經(jīng)過(guò)加工了)
Controller是View的代理(delegate)粮宛,以同步View與Controller
我們接下來(lái)討論V是如何向C發(fā)送信息的。V對(duì)C的交流有三種不同的方式:
第一種我們稱為目標(biāo)操作(target-action)
它是這樣工作的卖宠,C會(huì)在自己的內(nèi)部“懸掛”一個(gè)目標(biāo)(target)巍杈,如圖中的紅白相間的靶子
對(duì)應(yīng)的,它還會(huì)分發(fā)一個(gè)操作(action扛伍,如圖中的黃色箭頭)給將要和它交流的視圖對(duì)象(可能是屏幕上的一個(gè)按鈕)
當(dāng)按鈕被按時(shí)筷畦,action就會(huì)被發(fā)送給與之對(duì)應(yīng)的target,這樣V就可以和C交流了
但是在這種情況下刺洒,V只是知道發(fā)送action給對(duì)應(yīng)的target鳖宾,它并不知道C中的類,也不知道它到底發(fā)送了什么逆航。target-action是我們經(jīng)常使用的方法鼎文。
第二種方式我們叫做委托(delegate)
有時(shí)候,V需要和C進(jìn)行同步因俐,你知道拇惋,用戶交互不僅僅是什么按按鈕,劃滑塊抹剩,還有很多種形式
好了撑帖, 讓我們來(lái)看看圖中的delegate黃色箭頭,你發(fā)現(xiàn)箭頭上又分出了四個(gè)小箭頭:should澳眷,did胡嘿,will,還有一個(gè)沒(méi)標(biāo)注的
絕大部分的delegate信息都是should钳踊,will衷敌,did這三種形式
和英文意思相對(duì)應(yīng),should代表視圖對(duì)象將詢問(wèn)C中的某個(gè)對(duì)象“我應(yīng)該這么做么箍土?”
舉個(gè)例子逢享,有一個(gè)web視圖,有人點(diǎn)擊了一個(gè)鏈接吴藻,web視圖就要問(wèn)“我應(yīng)該打開(kāi)這個(gè)鏈接么瞒爬?這樣做安全么?”。這就是should信息
那 will和did呢侧但?will就是“我將要做這件事了”矢空,did就是“我已經(jīng)做了這件事”
C把自己設(shè)置為V的委托(delegate),它讓V知道:如果V想知道更多的關(guān)于將如何顯示的信息的話禀横,就向C發(fā)送delegate信息屁药。通過(guò)接受V發(fā)過(guò)來(lái)的delegate信息,C就會(huì)做出相應(yīng)的協(xié)調(diào)和處理
還有一點(diǎn)柏锄,每個(gè)V只能有一個(gè)delegate
第三種方式就是數(shù)據(jù)源(datasource)
V不能擁有它所要顯示的數(shù)據(jù)酿箭,記住這點(diǎn)非常重要
V希望別人幫助它管理將要顯示的數(shù)據(jù),當(dāng)它需要數(shù)據(jù)時(shí)趾娃,它就會(huì)請(qǐng)求別人的幫助缭嫡,把需要的數(shù)據(jù)給它
再者,iphone的屏幕很小抬闷,它不能顯示包含大量信息的視圖妇蛀。看圖中的datasource箭頭笤成,和delegate類似评架,V會(huì)發(fā)送cout,data炕泳,at信息給C來(lái)請(qǐng)求數(shù)據(jù)纵诞。
對(duì)于不同的UIView,有相應(yīng)的UIViewController喊崖,對(duì)應(yīng)MVC中的C挣磨。例如在iOS上常用的UITableView,它所對(duì)應(yīng)的Controller就是UITableViewController