7

私はNSArrayController, NSMutableArrayandを使用してNSTableView、独自のカスタム オブジェクトのリストを表示しています (ただし、バニラNSStringオブジェクトのリストだけを表示している場合でも、この質問はおそらく当てはまります)。

さまざまな時点で、配列をクリアし、データ ソースからデータを更新する必要があります。removeAllObjectsただし、オブジェクトを呼び出すだけでNSMutableArrayは KVO の更新がトリガーされないため、画面上のリストは変更されません。

NSArrayController利用可能なメソッドがありません removeAllObjects。これは本当に奇妙に思えます。(これaddObjectを使用してオブジェクトを追加し、KVO が確実にトリガーされ、UI が更新されるようにします。)

これを正しく発生させることができた最もクリーンな方法は次のとおりです。

[self willChangeValueForKey:@"myArray"];
[myArray removeAllObjects];
[self didChangeValueForKey:@"myArray"];

...そのため、KVO 通知を自分で手動で行う必要があります (これは、前述のように、myArrayプロパティを含むテスト アプリ クラスにあります)。NSMutableArray

これは間違っているようです - もっと良い方法はありますか? removeAllObjects私のグーグル検索から、 inの欠如に混乱している人が何人かいるようですが、NSArrayControllerより良い解決策は見られませんでした。

私はこの解決策を見てきました:

[self removeObjectsAtArrangedObjectIndexes:
  [NSIndexSet indexSetWithIndexesInRange:
    NSMakeRange(0, [[self arrangedObjects] count])]];

しかし、これは私にはさらに不快に見えます。少なくとも私の解決策は、少なくともわずかに自己文書化しています。

NSArrayControllerApple は、オブジェクトを介して管理されているリスト コントロールを空にしたい場合があることに気付かなかったのですか? これは当たり前のように思えるので、何かが欠けているに違いないと思います...

余談ですが、もちろん、( 経由でNSArrayController) 配列に新しい項目を追加すると、 で KVO 更新がトリガーされますがNSArrayController/NSTableView

  1. 何もないので、リストにアイテムを入れないことがあります。だからあなたはただ古いアイテムを見るだけです。
  2. これはとにかくヤバい。
4

5 に答える 5

16

テーブル ビューから項目を削除しません。アイテムはありません。別のオブジェクトのアイテムを表示するだけです。

配列コントローラーのコンテンツ配列バインディングを他のオブジェクトの配列プロパティにバインドした場合、そのオブジェクトのそのプロパティを操作する必要があります。を使用し[[object mutableArrayValueForKey:@"property"] removeAllObjects]ます。

一方、配列コントローラーのコンテンツ配列バインディングをバインドしていない場合は、それをcontent直接操作する必要があります。を使用し[[arrayController mutableArrayValueForKey:@"content"] removeAllObjects]ます。(arrangedObjectsの代わりにを使用することもできcontentます。一方が機能しない場合は、もう一方を試してください。配列コントローラーを別のものにバインドする最初の方法しか実行したことがありません。)

于 2009-03-14T23:38:08.043 に答える
3

この問題もあり、次のように解決しました:

NSArrayController* persons = /* your array controller */;
[[persons content] removeAllObjects];
于 2009-08-15T20:16:46.663 に答える
0

Swift での解決策:

if let ac = arrayController
{
    let range:NSRange = NSMakeRange(0, ac.arrangedObjects.count);
    let indexSet:NSIndexSet = NSIndexSet(indexesInRange: range);
    ac.removeObjectsAtArrangedObjectIndexes(indexSet);
}
于 2015-05-02T09:39:00.643 に答える
0

Swift 4 で動作する更新のみ:

let range = 0 ..< (self.arrayController.arrangedObjects as AnyObject).count
self.arrayController.remove(atArrangedObjectIndexes: IndexSet(integersIn: range))
于 2018-11-24T01:05:28.920 に答える