1. ホーム
  2. cocoa

NSMutableArray の挿入・削除の観察

2023-09-23 10:42:40

質問

あるクラスに、合成されたアクセサを持つ NSMutableArray 型のプロパティ (およびインスタンス変数) があります (via. @property ). を使ってこの配列を観察すると

[myObj addObserver:self forKeyPath:@"theArray" options:0 context:NULL];

そして、このような配列にオブジェクトを挿入します。

[myObj.theArray addObject:NSString.string];

observeValueForKeyPath...ノーティフィケーションは ではなく が送信されます。しかし、次のようにすると、適切な通知が送られます。

[[myObj mutableArrayValueForKey:@"theArray"] addObject:NSString.string];

これは mutableArrayValueForKey はオブザーバへの通知の世話をするプロキシオブジェクトを返すからです。

しかし、合成されたアクセサは自動的にそのようなプロキシオブジェクトを返してはいけないのでしょうか?これを回避する適切な方法は何でしょうか。 [super mutableArrayValueForKey...] ?

どのように解決するのですか?

<ブロッククオート

しかし、合成されたアクセサは自動的にそのようなプロキシオブジェクトを返すべきではないでしょうか?

いいえ。

<ブロッククオート

この問題を回避する適切な方法は何でしょうか。 [super mutableArrayValueForKey...] ?

いいえ、実装してください。 配列のアクセサー . これらを呼び出すと、KVOは自動的に適切な通知をポストします。つまり、あなたがしなければならないのは

[myObject insertObject:newObject inTheArrayAtIndex:[myObject countOfTheArray]];

で、「正しいこと」が自動的に行われます。

便宜上 addTheArrayObject: アクセサを書くことができます。このアクセサは、上で説明した実配列のアクセサのいずれかを呼び出すことになります。

- (void) addTheArrayObject:(NSObject *) newObject {
    [self insertObject:newObject inTheArrayAtIndex:[self countOfTheArray]];
}

(配列の中のオブジェクトの適切なクラスは NSObject .)

では、代わりに [myObject insertObject:…] の代わりに [myObject addTheArrayObject:newObject] .

悲しいかな add<Key>Object: とその対になる remove<Key>Object: は、私が最後に確認したところでは、KVOが認識するのは配列プロパティではなく、セット(NSSetのような)プロパティのみです。したがって、KVOが認識するアクセサの上に実装しない限り、それらを使用して無料のKVO通知を取得することはできません。これについては、x-radar://problem/6407437 というバグを提出しました。

私は アクセサーセレクタの全形式のリスト をブログで公開しています。