2012-01-18 9 views
9

私は最初のMacドキュメントベースのアプリケーションで作業しています。そのようなNSDocumentController nurを返すcurrentDocument

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

メインウィンドウコントローラとしてIがNSDocumentをサブクラスた

、再実装方法は、2つのNSViewControllerサブクラスが含まNSWindowsControllerのサブクラスです。

私が直面している問題は、これらのビューコントローラから現在のドキュメントにアクセスする必要があることです。私がしていることは、呼び出しです

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

最初は、アプリケーションの開始直後に新しい文書が作成されます。次に、メインウィンドウとそのビューコントローラが作成されますが、上記のメソッドはとなります。が返されます。ここで(のNSLogを使用して)、ログ私が手だ:、その後

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

、新しい文書を作成し、非nilのポインタでこのメソッドを呼び出すには、それは右の文書を指していませんが、最初の1へ:

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

お知らせその2番目の文書を作成した後、最初の文書にはない第二1へcurrentDocumentポイント。

ここで私が迷っていることや間違っていることは何ですか? NSDocumentControllerの場合、currentDocumentはいつですか? NSDocumentControllercurrentDocument上のアップルのドキュメントから

答えて

2

それは言う:そのアプリケーションが アクティブでないとき、それが呼び出された場合

このメソッドは、nilを返します。これは、ドラッグ&ドロップ操作の処理中に、たとえばreadSelectionFromPasteboard:の実装で などのように発生します。 そのような場合には、文書に関連付けられているNSViewのサブクラス からではなく、次のメッセージを送信します。

[[[self window] windowController] document];

これはそれが本当に「アクティブでない」何を意味するのか資格がないと少しあいまいです。ドラッグアンドドロップ操作が唯一のトリガーである可能性がありますが、アプリがアクティブにならない唯一のトリガーかどうかは記述されていません。

多分、Appleの推奨代替品があなたのものです。

+0

ありがとうございましたが、私はすでにそれを試みましたが、結果としてはまだゼロになっています。私はまた、 "アクティブではない"という意味ではAppleには意味がないと思っていましたが、私の場合は、アプリケーションの起動直後に起こります。ドラッグ・アンド・ドロップはありません。特別なものはありません。 – msoler

0

あなたNSViewControllerサブクラスであなたのNSWindowControllerサブクラスから-[self document](または-[[self window] document]を呼び出すことはできません何らかの理由?それは、これはココアで、ドキュメントベースのアプリケーションでどのように行われるか、通常です。基本的に

ときNSDocument(サブクラス)作成されると、NSWindowControllerをすべて作成してドキュメントに添付します。

さらに重要なことに、[[NSDocumentController sharedController] currentDocument]は、2つのドキュメントが開いていて、突然両方のコンテンツを描画する必要がある場合、適切な情報を返しません。代わりに、NSWindowControllerは、ウィンドウ内のビューへの情報の流れを制御して、フォアグラウンドとバックグラウンドの変更を同時に管理できるようになっています(アプリ内のすべてのウィンドウのバッキングストアが同時にリフレッシュされます)。

+0

ありがとうございます。 NSViewControllerサブクラスからはNSViewControllerに_window_プロパティではなく_view_プロパティがあるので、[[self window] document]を呼び出すことによってドキュメントにアクセスすることはできません。 NSViewControllerからNSViewと '[[[self view] window] windowController] document]'(@rogerが指すように)から[[[self window] windowController] document]を使用して、正しい文書を処理して返します。ウィンドウ/ビューが初期化されてから作業を行うことは重要ですが、それは私には分かりやすく理解できます。 – msoler

+0

申し訳ありませんが、私はあなたがNSViewControllerを使用していたという事実を忘れました。私はNSViewControllersを使用するときにMVCのパラダイムに多くなる別の答えを追加しました。これはもっと便利だと思っています。 – gaige

6

(以前の回答はNSViewのサブクラスを尋ねられたときに質問に答えたので、元のポスターはNSViewControllerを使用していたと言われているので、別の考慮事項があります)。

NSViewController制御されたビューの場合、NSViewControllerrepresentedObjectプロパティを使用してそのデータにアタッチされることを意図しています。この抽象化は、NSViewControllerのコントローラを含むコントローラによって管理されることを意図しています。コントローラのようなものはNSWindowControllerです。

カプセル化の程度に応じて、文書全体を操作する場合はNSViewControllerにプッシュするか、特定のNSViewControllerと密接な文書の情報だけをプッシュすることができます。

たとえば、電車に関する設計情報を編集するソフトウェア(エンジン、車、乗り物)を想定します。 NSDocumentサブクラスには、単一のエンジンオブジェクト、単一のキャブオブジェクト、および0個以上の車オブジェクトが含まれています。この場合、3つのNSViewがあり、それぞれオブジェクトのビューの内外へのデータの移動を処理する独自のNSViewControllerがあります。

NSWindowControllerは、理解しているオブジェクトに対してそれぞれNSViewControllerrepresentedObjectを設定します。たとえば、ビューの読み込みが完了したときに、ウィンドウ・コントローラは、次になります:

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

その後、あなたは(車が表示されているときに)車の一覧を表示するNSTableViewを使用し、でき、ウィンドウコントローラ可能性選択が変更された場合は[carViewController setRepresentedObject: car];を使用します(または、コードの構造に応じてバインディングを使用できます)。

コントローラは必要に応じてビューをモデルにリンクしますが、文書構造はトップレベルのNSWindowControllerによって実際に理解されるため、MVCパラダイムを最大限に活用します。