ホーム>source

私は、さまざまなNSWindows(数百)のLOTを備えたMacOSアプリキットアプリを持っていて、それぞれストーリーボードから作成されています。

これらのNSWindowsの多くには、複雑な埋め込みビュー/ビューコントローラ階層を持つコンテナビューがあります。

初期化中、特定のNSWindowに関連付けられたモデルオブジェクトを知っている必要があるため、そのサブビューとコントロールを適切に初期化できます。どのNSControllerもそのNSViewを知ることができ、どのNSViewもそのNSWindowを知ることができるため、その情報をNSWindowに保存しておくと便利です。

NSWindowの「representedObject」を設定するのは素晴らしいことですが、NSViewControllerとは異なり、実際にはありません。

NSWindowストーリーボードオブジェクトごとにシンプルなカスタムクラス(小さな基本クラスから派生)を作成する唯一の実際のソリューションは、ビュー階層の下のNSViewsとNSViewControllersがモデルデータ(ポインター)に到達できるようにするためですか?

明確化:何百ものストーリーボードにあるNSWindowオブジェクトのほとんどに、NSWindowから派生したカスタムクラスまたはコードがあります。したがって、カテゴリはAPIをクラスに追加してNSWindowに関連付けられているモデルデータにアクセスするのに役立ちますが、作成 プロパティまたはインスタンス変数とそれらすべてのNSWindowストーリーボードで初期化します。

最終的に私は簡単なものを提示しますが、誰もがコピーするべきではありません。

このアプリはNSDocumentを使用しません。NSDocumentは、NSWindowオブジェクトをドキュメント/モデルアーキテクチャに関連付ける機能を提供します。したがって、私たちの目標は、すべてのNSControllerとNSViewが、ビューのコントロールを初期化するために必要な適切な単一のドキュメントモデルオブジェクトにアクセスできるようにすることです。

Appleエンジニアリングの達人から、ビューとサブビューが作成および初期化される順序に依存できないと警告されました。そのため、データを複雑なストーリーボードに埋め込まれたサブビューに渡すのが難しく、エラーが発生しやすくなります。

ただし、すべてのUIがメインスレッド上にあるため、MacOS上の単一のアプリケーションが1つのストーリーボードを作成、初期化、および表示し、そのプロセスに別のストーリーボードの初期化と表示を中断させることはできません(少なくとも、ユーザーが呼び出すアプリケーションストーリーボードではできません)。 )。だから簡単な解決策は...

...持つため目的のドキュメントモデルポインタで一時的に設定されたアプリケーションレベルのグローバル。それと、上記の仮定に違反しないことを保証するスタックベースのロック数。ひどいデザイン効率的なソリューション

なぜこれが良くないのか、誰も私に思い出させる必要はありません。しかし、より良い解決策があれば、私のテストを免れた。私は、viewDidLoadとviewWillAppearでさえ、そのNSWindowへの確かなポインタを返すことは信頼できないことを発見しました...

あなたの答え
  • 解決した方法 # 1

    アプリケーションの構造を知らずに;モデルポインターを個々のウィンドウに割り当てるメカニズムが必要になります。これはいくつかのコードを追加する必要がありますどこかに。ウィズウィズ  サブクラスは適切に見えます。

    AppKit MVCパターンでは、モデルデータは通常、ビューとビューコントローラーの間に収まります。モデルをウィンドウに関連付けようとすると、ある程度このパターンに対抗できます。

    言われていること;Objective Cランタイムでは、カテゴリを使用して既存のクラスにカスタムプロパティを追加できます。これは、連想参照を使用して実現されます。関連する機能は次のとおりです。

    <前>ウィズウィズ

    この記事には、そのアプローチの利点と欠点の良いまとめがあります。

    NSWindow

  • 前へ java - JPAクエリ:サブクエリをグループ化条件に結合する
  • 次へ javascript - jqueryは成功後にページを更新します