41

私はプロジェクトで NSWindowController を数回使用しており、この重要なクラスの背後にある概念を (非常に) 大まかに把握しているように感じます。この投稿で私がやりたいことは、私自身の理解を明確化/修正し、うまくいけば他の学習者が理解への第一歩を踏み出すのを助けることです. これは、概念、概要、およびベスト プラクティスの概要であり、最も有用であり、ドキュメントに欠けていることがよくあります。これが NSWindowController に対する私の見解です (質問は太字で散りばめられています):

  • NSWindowController (NSWC) サブクラスは、(概念的には) すべてのウィンドウ nib のすぐ下に存在し、ユーザー インターフェイス要素とそれらが制御/表すモデル オブジェクトとの間の接着剤として機能します。基本的に、アプリケーション内のすべてのウィンドウには、独自の NSWC サブクラスが必要です。
  • nib のファイルの所有者は、常に NSWC サブクラスである必要があります。これは、MainMenu.xib アプリケーションにも当てはまりますか?
  • NSWCwindowプロパティは、常に InterfaceBuilder の NSWindow にリンクする必要があります。
  • を使用して「init」メソッドをオーバーライドする必要があります[super initWithWindowNibName:]。これにより、参照時に[mycontroller window]nib がロードされます。これは起動時に開かれますが、MainMenu.xib ウィンドウの NSWC にも当てはまりますか?
  • NSWC は重労働を行うべきではありません。単純にメッセージをオブジェクトのインスタンスに渡し、それらのオブジェクトを UI に表示する必要があります。
  • バインディングを使用したり、テーブルなどのデリゲートとして機能したり、変更を観察したときに UI 要素を積極的に変更したり、上記のいずれかの組み合わせを使用して UI を変更したりできます (どちらを使用するかは問題と思われます)。味、すべての側面に長所と短所があります)。
  • NSWC は、必要に応じて他の NSWC のインスタンスを作成できます (たとえば、1 回限りのサブウィンドウを開く場合)。
  • [mycontroller showWindow:nil]関連するウィンドウを前面に表示するには、 を使用します。ウィンドウをシートとして表示する場合は、次のようなものを使用します。

    NSWindowController* mycontroller = [[MyController alloc] init];
    [NSApp beginSheet: [mycontroller window]
       modalForWindow: [self window] 
        modalDelegate: self 
       didEndSelector: @selector(didEndMySheet:returnCode:contextInfo:)
          contextInfo: nil];
    

は親ウィンドウの NSWCのdidEndSelector:メソッドである必要があり、 で「mycontroller」にアクセスして解放できます[sheet windowController]。- ウィンドウを閉じるにはperformClose:、NSWC のウィンドウのメソッドを呼び出します。

いくつかの質問:

  • MainMenu ウィンドウの NSWC もアプリケーション デリゲートにする必要がありますか、それとも別のクラスにする必要がありますか?
  • 同じように、メインの NSWC がファイルを処理 (ドラッグ/ドロップして開く) する必要がありますか、それともアプリのデリゲートに渡す必要がありますか?それとも好みの問題ですか?

これのいずれかが悪い習慣であるか、単に間違っている場合は修正してください。NSWindowController についての理解を深めたいと考えているため、(ベスト プラクティス、経験、落とし穴の形で) 追加情報をいただければ幸いです。

ありがとう、ローリー

4

2 に答える 2

30

ウィンドウコントローラーは実際には何のためにあるのですか?

ウィンドウ コントローラは、NIB ファイルからウィンドウをロードし、NIB に割り当てられたリソースのメモリを管理するためのツールです。以前は、NSWindowControllers基本的にすべてのウィンドウに対して同じコードを記述するか、独自のウィンドウ コントローラー クラスを作成する必要がありました。

もちろん、これらはモデル/ビュー/コントローラーの意味でのコントローラーでもあるため、ウィンドウからのビューをモデル オブジェクトに接続するのに適した場所です。これを行うには、多くの場合、ビュー オブジェクトのデリゲートまたはデータ ソースとして機能する必要があります。したがって、この部分は完全に正しいです。

また、ウィンドウ コントローラはコードを再利用するためのツールです。これにより、ウィンドウ コントローラー クラスと XIB/NIB を別のプロジェクトに簡単にドロップして、そこで使用することができます。

はい、NIB のすべてのウィンドウは、1 つの例外を除いて、ウィンドウ コントローラーによって所有される必要があります。実際、これは良いコードのための単なるガイドラインであり、それを強制するものは何もありません。

WindowControllers と MainMenu.xib

MainMenu.xibウィンドウコントローラーを使用することはできません。このNIBはによってロードされるNSApplicationため、これは「ファイル所有者」でなければなりません。NSApplicationと NIB の間でウィンドウ コントローラを取得する方法はありません。また、アプリケーション オブジェクトはプログラムのランタイム全体にわたって存在するため、メモリ管理にウィンドウ コントローラーを使用する必要もありません。そのため、割り当てが解除されたときに NIB からリソースをクリーンアップする必要はありません。

メインウィンドウにウィンドウコントローラーが本当に必要な場合は、これをMainMenu.xib.

これが役立つことを願っています。ウィンドウコントローラーについても、おそらくもっと多くのことが言えます

于 2010-09-10T11:33:39.257 に答える
7

これは、MainMenu.xib アプリケーションにも当てはまりますか?

いいえ、MainMenu nib は NSApplication によって所有されています (それがロードされます)。

これは起動時に開かれますが、MainMenu.xib ウィンドウの NSWC にも当てはまりますか?

いいえ、NSApplication はアプリケーション ファイルの「NSMainNibFile」プロパティに基づいてメイン nib をロードします。(たまたまテンプレート Xcode プロジェクトで "MainMenu" にあらかじめ設定されています。) 名前を変更したい場合は、そこで変更します (そして nib ファイルの名前を変更します)。(ところで: このプロパティは、Xcode 4 のターゲットの「概要」ビューでも変更できます。)

MainMenu ウィンドウの NSWC もアプリケーション デリゲートにする必要がありますか、それとも別のクラスにする必要がありますか?

NSMainNibFile nib の所有者は、それをロードする NSApplication のインスタンスであり、関連付けによってそのインスタンスのデリゲートです。これらはどちらも NSWC サブクラスではありません。

同じように、メインの NSWC がファイルを処理 (ドラッグ/ドロップして開く) する必要がありますか、それともアプリのデリゲートに渡す必要がありますか?それとも好みの問題ですか?

「メイン NSWC」はありません (app/app-delegate は NSMainNibFile のコントローラーです)。

すべてのドラッグ アンド ドロップ操作は、NSWindow または NSView サブクラスによって処理されます。私は通常、すべてのドラッグ アンド ドロップ メソッドをデリゲートに渡すだけの特別な NSWindow または NSView サブクラスを使用します。例えば:

- (unsigned int) draggingEntered:sender
{
    return [[self delegate] draggingEntered:sender];
}

このようにして、すべてのウィンドウ/ビュー コードをそれぞれのコントローラーにまとめることができます (ペン先の所有者によって決定されます)。また、ウィンドウ/ビュー固有のコードが (NSWindow/NSView サブクラスではなく) コントローラーにあるため、さまざまなタイプの NSWindows/NSView がすべて同じドラッグ アンド ドロップ サブクラスを使用できます。

于 2011-04-09T17:58:00.817 に答える