2011-10-12 31 views
1

當加載使用NSPersistentDocument現有的文檔,作爲初始化的一部分,我想準備一些內容:是-makeWindowControllers初始化一個NSPersistentDocument最好的地方?

NSFetchRequest *req = [NSFetchRequest fetchRequestWithEntityName:@"DocumentRoot"]; 
    NSArray *results = [self.managedObjectContext executeFetchRequest:req error:NULL]; 
    if (results.count) self._docRoot = [results objectAtIndex:0]; 

當我把這個代碼-init,獲取請求不返回任何結果。

我在將我的NSPersistentDocument子類中的視圖控制器組件重構爲新的NSWindowController子類時遇到此問題。我曾經在-windowControllerDidLoadNib:中處理這個初始化,但是這不再被調用。

如果我的代碼擺脫-init-makeWindowControllers我得到我期望的結果。 -makeWindowControllers真的是準備這樣的內容的正確地點嗎?

回答

4

基礎上我已經得到了我覺得我做正確的事的反應,所以這裏是我的答案我自己的問題。

如果您正在使用的核心數據堆棧由NSPersistentDocument提供的,你不能在-init使用核心數據。

相反,你應該:

  1. 直接將文檔初始化代碼-windowControllerDidLoadNib: - 或者,如果您使用自定義NSWindowController子類中,-makeWindowControllers
  2. 您也可以將文檔初始化代碼抽象爲具有某個唯一名稱(如-setUpDocument)的幫助程序方法,然後從-makeWindowControllers/-windowControllerDidLoadNib:調用該方法。

如果您使用的是簡單的NSDocument,或者您自己設置了Core Data堆棧,則可以在-init中設置文檔模型。

+0

謝謝,這就是我尋找的東西,你應該清醒的唯一的事情是你無法保存上下文。無論如何,這是由NSDocument/NSPersistentDocument覆蓋。 – Stephan

+0

你是什麼意思 - 你不能在-makeWindowControllers中保存上下文? – paulmelnikow

+0

不要在'NSManagedObjectContext'實例上調用'save'' – Stephan

0

如果代碼是不是由init那是因爲你的文件正在初始化其他地方,如initWithContentsOfURL:ofType:error:initForURL:withContentsOfURL:ofType:error:initWithType:error:initWithCoder:makeWindowControllers不是設置數據調用。嘗試實現所有上述初始化程序並記錄下來,看看哪個被調用。

+0

代碼被調用。問題不在於此。它是關於在'-init'中'取回請求不返回結果'的。 – paulmelnikow

+0

我很抱歉我錯了。 (你原來的帖子並不清楚)。儘管如此,這並不是理由。 –

+0

我的問題是,「-makeWindowControllers是否是初始化NSPersistentDocument的最佳位置?」我認爲*在我原來的帖子中很清楚。我想你是對的;也許它沒有我想象的那麼清楚。抱歉。如果你編輯你的帖子,我會刪除投票。 – paulmelnikow

1

從這個問題和你約NSArrayControllers相關的問題,我收集你正在做這樣的事情:

- (void)makeWindowControllers 
{ 
    MyWindowController* wc = [[[MyWindowController alloc] initWithWindowNibName: [self windowNibName]] autorelease]; 
    [self addWindowController: wc]; 
} 

當你做到這一點,-windowControllerDidLoadNib:將不會被調用,因爲NSDocument對象如果你是這樣開始的話,那麼它不是Nib的所有者。如果你看一下NSDocument.h你會看到這樣的評論(見強調):

/* Create the user interface for this document, but don't show it yet. The 
default implementation of this method invokes [self windowNibName], 
creates a new window controller using the resulting nib name (if it is 
not nil), **specifying this document as the nib file's owner**, and then 
invokes [self addWindowController:theNewWindowController] to attach it. 
You can override this method to use a custom subclass of 
NSWindowController or to create more than one window controller right 
away. NSDocumentController invokes this method when creating or opening 
new documents. 
*/ 
- (void)makeWindowControllers; 

如果是你,而不是,這樣做:

- (void)makeWindowControllers 
{ 
    MyWindowController* wc = [[[MyWindowController alloc] initWithWindowNibName: [self windowNibName] owner: self] autorelease]; 
    [self addWindowController: wc]; 
} 

我相信你會發現-windowControllerDidLoadNib:被稱爲再次。這可能幫不了你,如果你有不是NSDocument一個很好的理由筆尖的所有者,但是這就是爲什麼-windowControllerDidLoadNib:不會被調用,什麼可以做,以獲得該行爲了。這幾乎可以肯定是一個比init更好的提取位置,這可能發生在所有必要的CoreData支持工具到位之前。所以這是一種選擇。

+0

你完全正確,我正在使用類似你的示例的代碼創建窗口控制器。我還創建了文檔擁有的打印視圖(這樣我就可以在不創建窗口的情況下打印),並從MOC中獲取數據。它工作正常,它感覺很奇怪。你是絕對正確的,我不應該在'-init'中進行初始化 - Core Data不起作用(儘管MOC被實例化了)。 – paulmelnikow

+0

根據您的建議更改nib所有者會導致調用'-windowControllerDidLoadNib:',但最終它只會與'-makeWindowControllers'中直接進行初始化不同,因爲它稍後會發生。 (這似乎並不是我的優勢 - 我寧願完全設置文檔,然後創建窗口控制器。) – paulmelnikow

+0

使模型控制器(NSPersistentDocument)成爲筆尖所有者似乎會取消分離視圖的好處 - 控制器(NSWindowController)。即使它們只涉及窗口控制器,我也不得不在「筆記」中爲在筆尖(日期格式化程序,數組控制器,附件窗口及其視圖控制器)中構建的視圖相關對象添加插口。 – paulmelnikow

相關問題