以下是對斯坦福大學ios開發裡面MVC模式的一段話的翻譯
主要的宗旨是把所有的對象分為3個陣營,model陣營,view陣營,或者是controller陣營
model(APP的目的)
舉個例子,你要做一個打飛機的游戲,那麼這個就是太空中這輛飛船的位置,什麼機型,每個飛船有多少機槍,護甲有多少等等。這就是model所做的事,而飛機在屏幕上的位置與model沒有關系。
model的作用是怎麼把model展現在用戶面前,它獲取了飛船在太空中的位置,然後算出怎麼在屏幕上展現出來。
這就是controller,controller控制如何在UI上展現model
view就是controller在僕人,view就是controller所使用的工具。我們盡可能地使view陣營裡面的對象通用化。
就像按鈕、滑動條等,這些都是蘋果自帶的。controller利用這些通用的view來做model所需要做的事,view應該是很通用的。因為系統上有好多view,還有和應用相關的功能來控制view。我們要更先進一點,利用通用的view來理解和使用這些功能。
controller向model發消息是100%被允許的,這個箭頭是綠色箭頭,controller可以問model任何問題,controller知道model的任何事情,因為controller就是用來把model展現在屏幕上,所有它要有完全的訪問權,這個箭頭是單向的,所以只有controller知道model,這裡面的像一個交通標志,從controller到model是白色虛線,所以可以隨時跨過去,等一會,我們會看到這個虛線不是一直是虛的。那麼controller和view的通信會是怎麼樣?也是綠色箭頭,controller是要吧model顯示在屏幕上,所以它可以對view做任何事。例如設個標志,讓view做些事情,在屏幕上排列view,數據通信,所以這條路也是白色的虛線,你們看見那個詞outlet
outlet是一個表達式用來表示controller的用來和view通信的一個屬性,所以我們要在controller裡創建outlets到view中去,那model和view怎麼樣?這門課的宗旨,它們永遠不會互相通信。我相信你們都理解為什麼model不和view通信,因為model和用戶交互界面無關,你可以有一個飛船射擊游戲的model,然後通過view來控制,移動飛船到XYZ,射擊,你可以這麼做,雖然比較笨但你可以這麼做。
所以model是完全ui獨立的,你們都應該明白model不應該和view通信,有些人說,我有一些自定義的view,掌控者model,所以能夠顯示model。這聽起來挺吸引人的,但這不是一個好主意的原因-重用。因為你吧view和model連在了一起,model變了以後view也要重寫,view不能被重復利用,model也不能被 其他ui用
比如iPad出來了,因為屏幕大小的原因需要一個新的ui,你就得重寫整個view,最好是把這部分放到controller裡,建一些更通用的view對象;另一個原因是,如果view和model通信,那麼現在所有人都能和model通信了,view和model通信 ,controller和model通信,model就有點hold不住了,如果只有controller和model通信就能很容易搞清楚程序在干嘛,所以把view排除在外,view只是controller的僕人,讓controller來通信。所以,在這門課上永遠不會發生view和model相互通信的情況,雙實線如果你越線我就給你開罰單。view能否允許和controller通信?答案是在某種程度上是可以的,所以這條線是黃色的。view(通用的)和controller(詳細控制如何在屏幕展現model)之間的通信是不可見的,view不知道之間在和誰說話,但有一個好的架構。所以在xcode我們可以很好的有組織的連接view和它的controller。所以,view向controller通信的方法,有結構的方法,一個被稱為target action。target action很簡單,就是controller自己畫了一個target,然後把一個action交個它的view。當view發生了一些事,比如按鈕被按滑動條被滑動,它會把action發到target,然後controller就知道按鈕被按了。這就是view向controller通信的機制,view回報controller發生了什麼。但是view對controller知道的並不多,只是簡單的發送target action。事實上,還有view和controller之間比較復雜的通信—比如view和controller要保持同步,所以常常view要告訴controller發生了什麼,這是圖上的did,或者將要發生什麼,這是will,或者要問controller我是否允許什麼發生,所以這些will,did,should是view要問的問題。這麼做的原因是因為controller把自己設成委托,用協議,希望你們都知道什麼是協議,我們會在obj-c裡會講到,設定一個協議,來回應will did should在一次,view不用知道回應的controller是哪個類 delegation是另一個view和controller通信的方法,另一個很重要的事是,view不是它顯示的數據的所有者,這很重要:所以用紅色來顯示,你們要了解view沒有數據,view只是一個平面,用來顯示數據,一個顯示信息的平台,view沒有 實體變量也不會去存儲,只有指向他們的指針,所以你iPod庫裡面 的1000首歌不會是view的實體變量,這種設計使得,比如view不會去管理數據庫,跟新iPod歌曲庫,這不是view干的活,而是controller或者model干的,如果view不擁有它所顯示 的數據,它如何獲得數據呢?一個類似delegation的方法,它又一些協議,比如這裡的data at和count,這對一個表挺有用的,表可以問表裡有多少東西 ,比如5000,那好我要地100到150條的數據,我要用來顯示 ,所以view去根據需求來請求數據,這會非常高效的,如果另外一頭知道怎麼管理一個巨大的數據庫,而只是提取其中需要的幾條,因為ipod裡有10000首歌,但屏幕上只顯示7首。你要這種功能,但不要把它寫在一個view裡,view是通用的用來顯示的,controller金額model一起來有效率的提供信息,類似地,view會有一個數據源的設置,controller會回應數據源,注意,數據源的delegation永遠是controller,或者是controller的指定的第三方,但不可能是model,controller的工作是把model的信息傳遞給view,響應所有的delegation。因為它能獲取model裡的數據,決定怎麼在屏幕上顯示,這是它的職能,所以它要參與這個循環,你們可能需要這些data at和count的方法,可能只是一行代碼,問model數據是什麼,然後model把數據給你,即使這是一行代碼,也需要controller來參與,因為這是controller的工作,獲取model顯示在屏幕上,我反復講了5編,這是controller的工作,在iOS開發這很重要,你要給他機會做他的工作,永遠不要越過view和model中間的線,還有一件事,model能向controller發話嗎這個很明顯,肯定不行的。model是ui獨立的,不能向controller發話,這是controller的工作來用view顯示model,那麼當model的一些東西改變了,你要更新controller的時候該怎麼辦呢?你有個數據庫,某人在數據庫裡寫了些東西,比如你的飛船游戲裡的其他玩家攻擊了你 的飛船,現在model改變了是因為飛船受傷了 。
在iOS裡面我們實現的方法是用一個廣播站就像信息廣播機制,有2個機制,通知關鍵數據監聽,當model改變了,它就在廣播站裡廣播,controller收聽到了,然後去model什麼東西改了。這是完全不可見的,同步的,這裡的kvo也可以用於view和controller但不會是view和model,view不會有面向model的廣播,view和controller會互相有廣播。model廣播非常好用,因為是不可見的,但也有限制,只能通知被允許通信的對象發生了什麼事,現在我們有了各個陣營間所有的通信機制,我們要建立一個復雜應用。復雜應用不僅僅只有一個controller。view可能有100個controller至少有十幾個控制很多的view,比如登錄界面,點擊了什麼出個表,再點一下出來個其他的什麼,各種各種的view被controller管理著,那要怎麼做復雜應用呢?答案是把mvc組合 成mvc群,圖上你們可以看到某些controller的view是另一個mvc,比如中間這個,它有3個mvc view,所以這很普遍,你在一個view裡按下了個按鈕,而另一個mvc顯示了數據,這個圖有個好的地方是,所有的箭頭只通過規定的界限。你看其中任何一個部分,你明白這部分是干嘛的,一個model只有一個controller