2011-10-30 17 views
4

私はNSArrayControllerにNSTableViewをバインドする最も単純なケースを実装しようとしています。そのため、NSTableViewはNSArrayによってサポートされています。ここでNSArrayControllerに裏付けられたNSTableView:なぜsetContent:IBは動作しませんか?

はセットアップです:

  1. 私はその「内容のアレイ」私のアプリデリゲートにNSArrayのにバインドされているNSArrayControllerはを持っています。
  2. NSArrayControllerの 'Object Controller'では、クラス名はNSArrayに含まれるオブジェクトの型であるModelに設定されます。
  3. NSTableViewの単一列の「値」は、Modelクラスの唯一のフィールドであるアレイコントローラの「arrangedObjects」のキー「name」にバインドされています。
  4. 私のアプリケーションデリゲートのapplicationDidFinishLaunching:では、NSArrayを初期化し、いくつかのModelオブジェクトを挿入します。

ただし、モデルに対応する行は、私も次の場合以外は表に表示されません。[self.arrayController setContent: self.array]

Interface Builderでバインディングを使用してこれを動作させる方法はありますか? NSArrayControllerの 'Content Array'がNSArrayに直接バインドされているため、プログラムでコンテンツを設定する必要はありません。なぜ私が束縛をよりよく理解するのに役立つかを知ること。

答えて

13

あなたのアレイコントローラは、あなたのApp Delegateの「配列」プロパティを監視しています。つまり、オブジェクトが追加されたときではなく、配列オブジェクトが設定されているときにのみKVO通知が送信されます。 NSMutableArrayを使用してオブジェクトを追加しているように思えます。なぜなら、基になるオブジェクトは変更されていないため、アレイコントローラに変更が通知されない理由を説明しています。これは、手動で「アレイ」プロパティへの変更があったことをオブザーバーに通知

[self willChangeValueForKey:@"array"]; 
[self.array addObject:[NSDictionary dictionaryWithObject:@"foo" forKey:@"name"]]; 
[self.array addObject:[NSDictionary dictionaryWithObject:@"bar" forKey:@"name"]]; 
[self didChangeValueForKey:@"array"]; 

簡単な解決策は意志であなたの呼び出しをラップすることです/そのような変更ブロックをしました。

長い答え:それは間違っています。配列コントローラを持つことの全体的なポイントは、配列の管理作業をコントローラクラス自体に移すことです。実装の詳細を汗ばませることなく、基底の配列を管理し、正しい通知を送信し、状態を維持します。よりよい解決策は、コンテンツ配列バインド外し、ちょうど直接そのようにアレイコントローラにオブジェクトを追加するには、次のようになります。

[arrayController addObject:[NSDictionary dictionaryWithObject:@"foo" forKey:@"name"]]; 
[arrayController addObject:[NSDictionary dictionaryWithObject:@"bar" forKey:@"name"]]; 

アレイコントローラが内部で独自の配列を管理しますので、これは動作します。

最高の解決策は、コアデータを使用することです。 NSArrayControllerは、それと共に使用するように設計されています。また、永続化、元に戻すサポート、オブジェクトのリレーションシップ、コードを記述しないでオブジェクトを追加する機能など、オブジェクトコントローラーのアレイコントローラーから直接add:をアレイコントローラーに直接呼び出すことで、無償でたくさんのものを得ることができます。

+0

ありがとうございました。私はNSArrayControllerが単純に配列を管理するのか、それとも1つのプロキシであるのかは明らかではありませんでした。あなたの答えから、それは後者のようです。 – jogloran

+0

そのバインディングは絶対に大丈夫ですが、それは間違っていません。はい - アレイコントローラがアレイの内容を処理します。しかし、オブジェクトを保存/復元したい場合はどうすればいいですか?これは(NSUserDefaultsにバインドされていない限り)配列コントローラによって行われません。バインディングとKVOソリューションを使用しているときは、閉じるとウィンドウを閉じるとウィンドウに保存することができます。 - どのように便利です! –

関連する問題