2011-10-07 53 views
2

我的應用程序 - 基於文檔的核心數據應用程序 - 正在經歷第二次迭代,現在需要多個窗口來管理多個模型對象。目前它通過一個窗口和一個控制器來管理事件和位置。標準生成的文檔類目前充當主窗口的控制器。基於Cocoa應用程序的多窗口文檔的最佳方法是什麼?

我現在想要一個單獨的窗口來管理位置模型對象。對於每個窗口都有一個單獨的控制器(NSWindowController)似乎是很好的設計,但後來我意識到這些控制器將無法訪問訪問模型對象所需的託管對象上下文。

這裏最好的辦法是什麼?

編輯:

我跟着ughoavgfhw溶液如下:

  • 創建一個新的XIB爲位置,並增加了陣列控制器加載位置對象
  • 創建的定製控制器ManageLocationsController作爲一個子類NSWindowController
  • 使自定義控制器成爲位置中的文件所有者XIB
  • 映射陣列控制器的情況下,以文件的所有者和的keyPath document.managedObjectContext

我打開位置窗口:

ManageLocationsController *aController = [[ManageLocationsController alloc] initWithWindowNibName:@"ManageLocations"]; 
[aController showWindow: self]; 

這是從EventDocument,這是由的XCode默認生成的類來完成。

映射數組控制器時,在keyPath字段中留下一個圓形的黑色感嘆號,當我打開Location窗口時,它會拋出一個異常,指出「不能在沒有管理對象的情況下執行操作」。顯然不好。我錯過了什麼?

回答

3

使用自定義窗口控制器是最好的方法。窗口控制器可能無法直接訪問受管對象上下文,但可以訪問文檔。您可以使用windowController.document.managedObjectContext或通過與關鍵路徑document.managedObjectContext綁定來以編程方式訪問它。如果要模擬直接訪問託管對象上下文,可以創建一個只讀屬性,從文檔中加載它。

// header 
@property (readonly) NSManagedObjectContext *managedObjectContext; 

// implementation 
- (NSManagedObjectContext *)managedObjectContext { 
    return self.document.managedObjectContext; 
} 
+ (NSSet *)keyPathsForValuesAffectingManagedObjectContext { 
    return [NSSet setWithObject:@"document.managedObjectContext"]; 
} 

keyPathsForValuesAffectingManagedObjectContext方法用於告訴觀察managedObjectContext屬性的任何對象應通知的變化每當路徑返回變化鍵值觀測系統。

爲了使窗口控制器正常工作,必須使用addWindowController:將它們添加到文檔中。如果在文檔打開時創建多個窗口,則應在文檔方法中覆蓋makeWindowControllers以創建窗口控制器,因爲這將在正確的時間自動調用。如果您要求創建窗口控制器,您可以使用任何您想要的方法制作窗口控件,只需確保將它們添加到文檔中即可。

[theDocument addWindowController:myNewController]; 

至於IB中的小黑色驚歎號,您將不得不忽略它。NSWindowControllerdocument屬性定義爲類型NSDocument,但managedObjectContext屬性由NSPersistentDocument子類定義。國際文憑組織警告你,該財產可能不在那裏,但你知道它會是這樣,你可以忽略它。

+0

非常感謝。我已根據您的答案編輯了結果的問題。 – Roger

+0

@Roger對不起,我忘了添加關於使用自定義窗口控制器與NSDocument的細節。我現在補充一下。 – ughoavgfhw

+0

謝謝你。這雖然有所幫助,但現在我得到了「此類不是關鍵的managedObjectController的符合關鍵值編碼」例外。我懷疑這與keyPathsForValuesAffectingManagedObjectContext方法有關。我是否需要在自定義控制器類中實現該方法? – Roger

相關問題