1

使用 加载现有文档时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

3 回答 3

5

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

如果您使用的是 NSPersistentDocument 提供的 Core Data 堆栈,则不能在-init.

相反,您应该:

  1. 将文档初始化代码直接放入-windowControllerDidLoadNib:- 或者如果您使用自定义 NSWindowController 子类,则放入-makeWindowControllers.
  2. 您还可以将文档初始化代码抽象为一个具有唯一名称(如 )的辅助方法,并从/-setUpDocument调用该方法。-makeWindowControllers-windowControllerDidLoadNib:

如果您使用的是普通的 NSDocument,或者您自己设置 Core Data 堆栈,您可以在-init.

于 2012-01-31T17:55:58.637 回答
2

从这个问题和你关于 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 支持东西到位之前。所以这是一种选择。

于 2012-01-05T20:55:09.850 回答
0

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

于 2011-11-28T11:21:59.013 回答