2011-07-08 32 views
9

我想了解如何更好地實現模型 - 視圖 - 控制器設計模式。Cocoa/iOS/iPhone中的模型對象所有權和MVC

什麼對象應該擁有Model對象?單個Controller是否應該實例化(擁有)Model對象?

下面是一個例子情形:

我有含有兩個UIViewControllers(controllerA和controllerB)一個的UITabBarController。很明顯,這些控制器都不相互擁有。我有一個Model對象,它包含一些數據並執行一些網絡活動。 controllerA和controllerB都需要能夠對Model對象進行更改。 controllerB需要知道何時對Model對象進行更改(由controllerA或網絡活動返回的結果)。從最近的閱讀:

  • 我需要模型對象和controllerB之間的KVO?
  • 模型對象應該是單身嗎?這樣兩個控制器都可以修改它?
  • 在更簡單的應用程序中,我有viewController擁有Model對象。有沒有辦法讓一個控制器實例化Model對象,但其他控制器是否有寫入權限?
  • 我也讀過關於使用應用程序委託來擁有Model對象,並允許控制器通過應用程序委託共享實例進行訪問。這看起來很醜陋 - 使用應用程序委託單例來全局訪問我的Model對象。將我的Model對象設置爲singleton不是更好嗎?
  • 我看到有人給了this鏈接到iPhoneDevSDK,但他的方法的原因逃脫了我。同樣,這不是讓應用程序委託涉及的東西應該是單身?

主要是,有沒有其他方式讓兩個控制器訪問(寫入)一個模型,而不是通過模型作爲單例?另外,當一個Controller擁有另一個Controller(例如,在一個UINavigationController中,當根視圖控制器實例化另一個視圖控制器時,它將自己堆疊在另一個視圖控制器上),共享該模型的最佳方法是讓根視圖控制器實例化模型,然後將其傳遞到下一個視圖控制器,然後再將其推送到導航堆棧上)?

回答

8

在項目擴展時,將全局對象存儲在AppDelegate中會變得非常難看。

問問自己:這個模型對象和我的應用程序中的其他對象之間有什麼關係?關係是1對1還是1對1。如果你只需要一個模型被不同的對象訪問,那麼去單例方法。如果你需要一個對象只有一個模型,那麼在該對象中保留一個指向它的指針。

當面對不同的,但計算正確,設計方案几方面考慮

  1. 哪種方法最大限度地降低代碼行?
  2. 哪種方法導致最少量的耦合和語義耦合?
  3. 從項目新手程序員的角度來看,哪種方法更容易理解,維護和更難以引入錯誤。

如果您開始將全局模型拖放到AppDelegate中,您最終會創建一個難以理解且難以維護的整體類。如果您在每個控制器中創建一個指向模型的指針,則每次實例化新控件時都必須傳遞對該模型的引用,並且必須將指針傳遞給它實例化的任何需要的對象。本質上,你已經創建了一個傳遞相同指針的級聯瀑布,它膨脹了你的接口文件和構造函數。想象一下,如果您需要跟蹤5個模型對象,而不是1個模型。對於需要傳遞5個模型的5個指針的對象是否有意義 - 每次都要傳遞給構造函數?這是如何讓你的項目越野車和不可維護的。

如果不明顯。 AppDelegate只是一個單身人士。當你在你的應用程序委託中展示所有模型時,你並沒有避免使用單例,而是創建了一個單一的模型。

關於KVO:這取決於你想要完成什麼。我將舉例說明KVO的用處。假設您有一個存儲應用程序用戶首選項的模型對象。

@interface SettingsModel 
..... 
@property (nonatomic, retain) UIColor * backgroundColor; 
@end 

應用程序中的其他視圖應該在此設置更改時立即更新它們的背景顏色。這可以很容易地使用國際志願者組織來解決:

[[SettingsModel getInstance] addObserver:self forKeyPath:@"backgroundColor" options:0 context:nil]; 


- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { 
    if ([keyPath isEqualToString:@"backgroundColor"]){ 
     self.view.backgroundColor = [[SettingsModel getInstance] backgroundColor]; 
    } 
} 
+0

感謝lorean,很好的回答!非常感激。 – MattyG

0

該模型可以被多個控制器引用。爲了深入瞭解iPhone開發中模型 - 視圖 - 控制器的基礎知識,請瀏覽斯坦福大學iPhone開發課程的前兩個講座(可在iTunesU免費下載,參見斯坦福大學的信息http://www.stanford.edu/class/cs193p/cgi-bin/drupal/)似乎有更多的方法讓控制器瞭解有關視圖和/或型號更新的信息。

我不知道爲什麼你被困在一個單身人士,我也沒有看到在製作一個單身人士模型對象的問題。我認爲你也需要考慮線程安全和內存泄漏。

+0

羅爾夫你好,我想諮詢一下,因爲單身,我不知道任何其他方式對兩個控制器(沒有一個人擁有對方的)寫入同一型號目的。你知道一種方式嗎?我看過那些講座,謝謝。 – MattyG

+0

嗨馬特,不知道,沒有完成該課程;-)我知道沒有可可的依賴注入框架,所以現在我說單身是好的。 – Rolf