1

を使用して既存のドキュメントをロードするときNSPersistentDocument、初期化の一部として、いくつかのコンテンツを準備したいと思います:

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

このコードを に挿入する-initと、フェッチ リクエストは結果を返しません。

NSPersistentDocumentView-Controller コンポーネントをサブクラスから新しいサブクラスにリファクタリングしているときに、この問題が発生しましたNSWindowController。以前は でこの初期化を処理していまし-windowControllerDidLoadNib:たが、それは呼び出されなくなりました。

コードを から に移動する-initと、-makeWindowControllers期待どおりの結果が得られます。-makeWindowControllersこのようなコンテンツを準備するのに本当に適切な場所はありますか?

4

3 に答える 3

5

私が得た回答に基づいて、私は正しいことをしていると思うので、ここに私自身の質問に対する私の答えがあります.

NSPersistentDocument が提供する Core Data スタックを使用している場合、 で 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サポートがすべて配置される前に発生する可能性があります。これが1つのオプションです。

于 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 に答える