2012-07-26 81 views
3

這可能是一個愚蠢的問題,但在MVC中,視圖並不知道模型的權利。我已經看過表格視圖單元格的一些示例,並且表格視圖單元格具有模型對象的屬性。然後使用該模型的屬性來填充標籤或單元格的圖像。或者在另一種情況下,如果我有一個UIView根據模型動態繪製某些東西,看起來像在UIView上擁有一個屬性最簡單,所以UIView可以訪問該模型的數據以繪製它動態地。所以我可以做這樣的事情:MVC,瞭解模型的意見

myView.object = newObject; 
[myView setNeedsDisplay]; 

這是錯誤的MVC?如果是這樣,有什麼更好的方法來做這兩件事情?謝謝。

回答

0

或者在其他情況下,如果我有一個UIView動態畫點什麼 基於在模型上,似乎在UIView上擁有 屬性是最容易的,因此UIView可以訪問 中的模型數據以便動態繪製它。

那麼,爲了獲得正確的信息,你對模型有什麼看法?爲了提出正確的問題,它必須瞭解模型的一些內容,對吧?或者,您可以定義像UITableViewDataSource這樣的協議併發送類似-cellForRowAtIndexPath:的通用消息,然後在您的模型中實現該協議。這避免了視圖需要知道關於模型的任何具體內容,但它意味着模型現在必須瞭解視圖 - 它必須知道視圖中應顯示的內容,以便它可以通過取回正確的數據。無論你走到哪裏,你都會引入模型和視圖之間的依賴關係,這意味着當你對其中一個進行修改時,你必須對另一個進行修改。

避免這些類型的依賴關係正是MVC體系結構的要點。控制器知道模型和視圖,這允許模型和視圖彼此獨立存在。

讓模型和視圖都知道一些對象有時候可能是有意義的。如果您正在編寫通訊簿,那麼讓知道如何顯示聯繫人的聯繫人視圖以及存儲聯繫人對象的模型可能是有意義的。這似乎比擁有一個完全愚蠢的視圖更明智,它可以讓你傳遞聯繫人對象而不是很長的名單,地址,電話,傳真,電子郵件等名單。你可以說聯繫人是一個模型對象,以上所有情況都適用:您將在ContactView和Contact之間引入依賴關係。但通常當我們談論「模型」時,我們指的是程序用來存儲其數據的整個對象圖,MVC的好處是將您管理所有對象的方式與呈現數據的方式分開他們包含。

0

首先:沒有「MVC模型」。用不同的方式概括了它們的差別,但重要的區別。

如果視圖中的某個組件需要獲取信息,它可以通過兩種方式獲取:請求它(輪詢)或通知它(推送)。在大多數情況下,通知應該是更清潔的方法,因爲該視圖實際上不知道模型的任何內容,它只是作爲observer運行。

但是,GUI組件傾向於需要「模型對象」來存放數據並且可以請求它,就像在你的例子中一樣。儘管它們通常以模型命名,但在體系結構上它們不需要屬於它。在我看來,他們不應該這樣做,因爲模型的接口是在預定義GUI組件的需求之後構建的,並且MVC的整體意義消失了。如果你想模型之間的明確分工,並查看你應該嘗試這樣的事:

-----------------  -----------------  --------------  --------- 
| GUI Component | ---> | "Model Class" | <--> | Controller | ---> | Model | 
-----------------  -----------------  --------------  --------- 

所以由GUI組件所期望的「模型類」的對象是什麼,但對於控制器的適配器。在GUI和Controller之間的這種關係中,您現在可以實現您喜歡的任何策略 - 輪詢或推送(雙向箭頭的原因)。

4

MVC模型有不同的變體--Cocoa的蘋果文檔在這裏:http://developer.apple.com/library/mac/documentation/General/Conceptual/CocoaEncyclopedia/Model-View-Controller/Model-View-Controller.html#//apple_ref/doc/uid/TP40010810-CH14-SW9

我從中獲取的主要內容是:視圖不應與模型直接相關。看到這個圖:

Apple diagram of Cocoa MVC pattern

你提到UITableViewCells經常具有模式對象的屬性 - 我建議這是錯誤的。這個模式應該如下:

  • 模式處理所有實際的數據存儲和管理的
  • 查看知道數據的類型正在顯示,而不是數據本身。
  • 控制器(UITableViewController中)是「膠水」,從模型中獲取數據,並設置了查看

在實踐中如何工作的呢?

請原諒以下僞代碼中的一些錯誤,因爲我只是直接輸入它,我沒有測試過它,但希望它顯示了一點。

所以,你有一個UITableViewCell子類,它看起來是這樣的:

@interface PhoneEntryTableViewCell { 

@property (weak) IBOutlet UILabel *personName; 
@property (weak) IBOutlet UILabel *phoneNumber; 

} 

模式看起來是這樣的:

@interface PhoneModel { 

@property (strong) NSMutableArray *listOfPeople; 

} 

而且UITableViewController實現標準UITableViewDelegate/UITableViewDataSource方法,例如:

- (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath { 

    Person *person = [myModel personForIndex:indexPath.row]; 

    PhoneEntryTableViewCell *cell = [self dequeueReusableCellWithIdentifier:@"PhoneCell"]; 
    cell.personName.text = [person name]; 
    cell.phoneNumber.text = [person phoneNumber]; 

    return cell; 
} 

因此,總之,查看不知道實際的數據 - 它只知道它必須顯示一個人的姓名和電話號碼。它不知道後端存儲是什麼 - 它可能是核心數據,文件,下載和解析的JSON等。它不知道任何關於模型 - 例如,它可能存儲其他數據關於該人,也許電話號碼實際上存儲在與名稱不同的模型中。 控制器可以處理所有這些工作。

爲什麼這樣呢?

所以你推出上述應用程序,然後發現你的型號是可怕的慢的 - 你可以將其交換出去完全不同的模型,而不會觸及查看。也許你可以讓其他開發人員或設計人員創建查看 - 他們需要知道的一點是它必須顯示兩位文本。基本上它允許你的代碼乾淨,分區清晰,易於擴展,並且更容易重構。

現在,只要你做這樣的事情在你的UITableViewCell查看,這一切都消失了:

@property (strong) Person *person;