3

重複の可能性:
1回のKVC変更に対して2つのKVO通知を受信する

どこで使うべきか迷っていwillChangeValueForKey:ますdidChangeValueForKey:

カスタムセッターメソッドを必要とするプロパティを持つオブジェクトがあります。Appleのドキュメントによると、私は以下を使用していwill/didChangeValueForKey:ます:

手動のオブザーバー通知を実装するには、値を変更する前にwillChangeValueForKey:を呼び出し、値を変更した後にdidChangeValueForKey:を呼び出します。リスト3の例は、openingBalanceプロパティの手動通知を実装しています。

リスト3 手動通知を実装するアクセサーメソッドの例

- (void)setOpeningBalance:(double)theBalance {
    [self willChangeValueForKey:@"openingBalance"];
    _openingBalance = theBalance;
    [self didChangeValueForKey:@"openingBalance"];
}

これにより、私のオブジェクトは次のようになります。

@interface cObject
@property (readwrite, nonatomic) BOOL Property;
@end

@implementation cObject
- (void)setProperty:(BOOL)Property
{
   [self willChangeValueForKey:@"Property"];
   _Property = Property;
   [self didChangeValueForKey:@"Property"];
   //Do some other stuff
}
@end

私の混乱の原因は、Propertyのインスタンスを監視するために別のオブジェクトを設定してcObjectから呼び出す[myObject setProperty:]と、オブザーバーのコールバック関数が2回ヒットすることです。スタックを見る:最初のヒットは私が呼び出した結果として発生しdidChangeValueForKey:、2番目のヒットは私が呼び出した直接の結果ですsetProperty:(つまり、私のカスタムセッターはスタックに表示されません)。

さらに混乱を増すために、_Property他の場所で別の関数を変更してもcObject、オブザーバーには通知されませdid/willChangeValueForKey:ん(もちろん、使用しない限り)。

編集:カスタムセッターを変更しなくても_Property、KVOはオブザーバーに変更を通知します。このことから、何かが変わったかどうかに関係なく、セッターを呼び出した結果としてKVOが呼び出されていると結論付けます...

私の状況がドキュメントで説明されている状況とどのように異なるかを誰かが説明できますか?

4

1 に答える 1

6

ドキュメントから。手動が必要な場合は、それをオーバーライドする必要があります。

手動変更通知

手動の変更通知により、通知をオブザーバーに送信する方法とタイミングをより細かく制御できます。これは、不要な通知のトリガーを最小限に抑えたり、多数の変更を1つの通知にグループ化したりするのに役立ちます。

手動通知を実装するクラスは、automaticallyNotizesObserversForKey:のNSObject実装をオーバーライドする必要があります。同じクラスで自動オブザーバー通知と手動オブザーバー通知の両方を使用することができます。手動通知を実行するプロパティの場合、automaticallyNotizesObserversForKey:のサブクラス実装はNOを返す必要があります。サブクラスの実装では、認識されないキーに対してsuperを呼び出す必要があります。リスト2の例では、openingBalanceプロパティの手動通知を有効にして、スーパークラスが他のすべてのキーの通知を判別できるようにします。

于 2013-01-04T14:23:27.880 に答える