標籤:
iOS裡面MVC模式詳解
MVC是IOS裡面也是很多程式設計裡面的一種設計模式,M是model,V是view,C是controller。MVC模式在ios開發裡面可謂是用得淋漓盡致。
以下是對斯坦福大學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
iOS裡面MVC模式詳解