-makeWindowControllers是初始化NSPersistentDocument的最佳位置吗?

时间:2011-10-12 02:45:23

标签: cocoa core-data nspersistentdocument

使用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真的是准备这样的内容的正确位置吗?

3 个答案:

答案 0 :(得分:5)

根据我得到的回答,我认为我做的是正确的,所以这是我对自己问题的回答。

如果您使用的是NSPersistentDocument提供的核心数据堆栈,则无法在-init中使用核心数据。

相反,你应该:

  1. 将文档初始化代码直接放在-windowControllerDidLoadNib:中 - 或者如果您使用自定义的NSWindowController子类,则放在-makeWindowControllers中。
  2. 您也可以使用-setUpDocument这样的唯

    如果您使用的是普通的NSDocument,或者您自己设置了Core Data堆栈,则可以在-makeWindowControllers中设置文档模型。

答案 1 :(得分: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:。如果你有充分的理由认为Nib的所有者不是NSDocument,那可能对你没有帮助,但这就是为什么-windowControllerDidLoadNib:没有被调用,以及你可以做些什么来恢复这种行为。这几乎肯定是一个比在init中更好的取件,这可能发生在所有必要的CoreData支持之前。所以这是一个选择。

答案 2 :(得分:0)

如果未从init调用代码,因为您的文档正在其他位置初始化,例如initWithContentsOfURL:ofType:error:initForURL:withContentsOfURL:ofType:error:initWithType:error:initWithCoder: makeWindowControllers不是用于设置数据。尝试实现所有上述初始化程序并记录以查看调用的内容。