2012-01-18 20 views
9

我正在處理我的第一個基於文檔的Mac應用程序。NSDocumentController currentDocument返回零

我已經子類NSDocument,重新實現方法如

- (BOOL)readFromURL:(NSURL *)absoluteURL ofType:(NSString *)typeName error:(NSError **)outError; 
- (BOOL)writeToURL:(NSURL *)absoluteURL ofType:(NSString *)typeName error:(NSError **)outError; 
- (void)makeWindowControllers; 

主窗口控制器的NSWindowsController一個亞類中,包含兩個NSViewController子類。

我面臨的問題是我需要從這些視圖控制器訪問當前文檔。我所要做的就是打電話

MyDocument *myDocument = [[NSDocumentController sharedController] currentDocument]; 

首先,在啓動應用程序之後,創建一個新文檔。然後,創建主窗口及其視圖控制器,但上述方法返回。這裏的日誌(使用的NSLog)我得到:

Just created this new document: <MyDocument: 0x10040ff10> 
I'm in a view controller and current document is (null) 

之後,創建一個新的文件,並呼籲在一個非空指針這種方法的結果,但它並沒有在正確的文件指出,但到第一個:

Just created this new document: <MyDocument: 0x100437e10> 
I'm in a view controller and current document is <MyDocument: 0x10040ff10> 

注意,第二個文檔創建之後,currentDocument指向第一個文件,而不是第二個。

任何想法,我在這裏失蹤或做錯了? currentDocument何時設爲NSDocumentController

回答

2

從上NSDocumentControllercurrentDocument蘋果的文檔,它說:

該方法返回nil,如果當其應用是不活躍 它被調用。這可能會在處理拖放操作期間發生,例如,在readSelectionFromPasteboard的實現中: 。在 這種情況下,從與文檔相關聯的一個NSView 子發送下面的消息,而不是:

[[[self window] windowController] document];

這是微渺,因爲它並沒有真正符合什麼「不活躍」的意思。可能是拖放操作是唯一的觸發器,但它並沒有說明這是否是應用程序不活動的唯一觸發器。

也許Apple建議的替代方法對您有用。

+0

謝謝,但我已經試過,我仍然得到零結果。我也不確定蘋果公司的「非主動」意味着什麼,但在我的情況下,它恰好在啓動應用程序後發生。沒有拖放,沒有什麼特別的。 – msoler

0

任何原因,你不能在你的NSViewController子類中調用從NSWindowController-[self document](或-[[self window] document]?這就是通常這是如何在可可基於文檔的應用程序來完成。

基本上當NSDocument(子)它會創建所有NSWindowControllers並將它們附加到文檔中。

更重要的是,[[NSDocumentController sharedController] currentDocument]不會,如果你有2個文件打開,突然需要藉助兩者的內容返回正確的信息。相反,NSWindowController應該控制信息流到其窗口中的視圖,以便您可以同時管理前景和背景更改(例如,如果應用中所有窗口的後備存儲需要同時刷新)。

+0

謝謝。在NSViewController子類中,通過調用'[[self window] document]'來訪問文檔是不可能的,因爲NSViewController具有_view_屬性而不是_window_屬性。在NSViewController中使用'[[[self window] windowController] document]'和NSViewController的'[[[self view view] window] windowController] document]'(如@roger指出的)做功並返回正確的文檔。重要的是要提到,一旦窗口/視圖被初始化,它們就會工作,這對我來說是很好的和可以理解的。 – msoler

+0

對不起,我錯過了你使用NSViewControllers的事實。我在使用NSViewControllers時添加了更多的MVC範例。希望這個更有用。 – gaige

6

(我要離開,以取代之前的答案,因爲它回答時問的NSView的一個子類,但現在,原來的海報已表示他使用NSViewController的問題,也有不同的考慮)。

對於NSViewController受控視圖,NSViewController旨在通過使用representedObject屬性附加到其數據。這個抽象意圖由NSViewController的包含控制器來管理,聽起來像是您的NSWindowController

根據您希望/需要提供多少封裝,您可以將文檔推送到NSViewControllers(如果它們在整個文檔上操作),也可以僅從文檔中推送與特定NSViewController相關的信息。

例如,我會承擔的軟件,編輯有關列車的設計信息:發動機,汽車,和守車。 NSDocument子類包含單個引擎對象,單個對象和0個或更多個汽車對象。在這種情況下,您可能有3個NSView,每個都有自己的NSViewController來處理從其對象中移入和移出視圖的數據。

NSWindowController處理將每個NSViewControllerrepresentedObject設置爲它理解的對象。例如,當意見完成加載,窗口控制器接着會:

[engineViewController setRepresentedObject: engine]; 
    [cabooseViewController setRepresentedObject: caboose]; 

然後,你可以使用一個NSTableView顯示汽車的列表,(正在看車的時候),窗控制器可然後在選擇更改時使用[carViewController setRepresentedObject: car];(或者可以使用綁定,具體取決於代碼的結構)。

這樣,您可以充分利用MVC範例,因爲控制器根據需要將視圖鏈接到模型,但文檔結構只能由頂級NSWindowController真正理解。