これはCocoan00bの質問です-私は他の環境で何年もGUIアプリケーションをプログラミングしてきましたが、次の些細な状況での「慣用的なCocoa」とは何かを理解したいと思います。
NSView
ユーザーがその中に簡単な形を描くことができる簡単な習慣があります。そのdrawRect
実装は次のようになります。
- (void)drawRect:(NSRect)rect
{
// Draw a white background.
[[NSColor whiteColor] set];
NSRect bounds = [self bounds];
[NSBezierPath fillRect:bounds];
[[NSColor blackColor] set];
// 'shapes' is a NSMutableArray instance variable
// whose elements are NSValues, each wrapping an NSRect.
for (NSValue *value in shapes)
{
NSRect someRect;
[value getValue:&someRect];
[self drawShapeForRect:someRect];
}
// In addition to drawing the shapes in the 'shapes'
// array, we draw the shape based on the user's
// current drag interaction.
[self drawShapeForRect:[self dragRect]];
}
このコードがいかに単純であるかがわかります。shapes
配列インスタンス変数は、drawRect
メソッドが形状を描画するために使用するモデルとして機能します。ユーザーがマウスダウン/ドラッグ/マウスアップシーケンスを実行するたびに新しいNSRect
が追加されます。これもこのカスタムビューに実装されています。shapes
これが私の質問です:
これが「本物の」Cocoaアプリケーションである場合、カスタムビューがモデルを更新するための慣用的な方法は何でしょうか。
つまり、カスタムビューは、別の図形を図形のリストに追加する必要があることをコントローラーにどのように通知する必要がありますか?現在、ビューはそれ自体NSMutableArray
で形状を追跡します。これは実装の詳細としては問題ありませんが、カスタムビューのパブリックAPIの一部としてこの配列を公開したくありません。さらに、エラーチェック、保存/読み込み、元に戻すコードを、カスタムビュー全体に散らかすのではなく、コントローラーのような一元化された場所に配置したいと思います。他のGUIプログラミング環境での過去の経験では、モデルはコントローラーレイヤーのオブジェクトによって管理され、ビューは通常、モデルを直接更新しません。むしろ、ビューは、何かが発生したとき、イベントをディスパッチすること、またはを呼び出すことによって通信します。コントローラー上のメソッドへの参照があるか、同様に分離されたアプローチを使用します。
私の直感では、慣用的なCocoaコードはdelegate
、カスタムビューのプロパティを公開し、MyDocument
コントローラーオブジェクト(またはドキュメントコントローラーからぶら下がっている別のコントローラーレイヤーオブジェクト)を、xibファイルのデリゲートとしてビューにワイヤリングします。次に、ビューshapeAdded:(NSRect)shape
はデリゲートのようないくつかのメソッドを呼び出すことができます。ただし、これを行う方法は他にもたくさんあるようです。たとえば、コントローラーにモデルオブジェクト(形状のリスト)への参照をカスタムビューに直接渡す(気分が悪い)、ビューに通知をディスパッチさせるなどです。コントローラーがリッスンし(扱いにくいと感じます)、コントローラーがモデルを更新します。