5

次のコードを使用して、オブジェクトに KVO を追加します。

[self.model addObserver:self
             forKeyPath:@"userName"
                options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
                context:nil];

ここで、以下のように userName を設定したいと思います。はい、KVO をトリガーします。

self.model.userName = @"testUser";

ただし、トリガーKVOなしで値を設定したいです。どうやってするか?それを可能にする以下のような方法はありますか?

[self.model setValue:@"testUser" forKey:@"userName" isSilent:YES];
4

3 に答える 3

6

Core DatasetPrimitiveValue:forKey:は、これを可能にするために実装されています。オブジェクトに同じメソッドを実装できます。

[self.model setPrimitiveValue:@"testUser" forKey:@"userName"];

ただし、これを行う場合は、オブザーバーが最終的に手動で通知される集約通知のコンテキスト内にある必要がありwillChangeValueForKey:ますdidChangeValueForKey:

于 2013-01-27T01:24:22.643 に答える
5

これを行う場合、設計が壊れています。キー値監視のポイントは、フィールドが変更されたときに誰かが知りたいので、通知を登録することです。キー値の監視に準拠するポイントは、システムの残りの部分がどのように対話するかについて、オプションを開いたままにしておくことです。

あなたがしているように聞こえるのは、何らかの理由でプロパティの真の価値を誰かに知られたくないという問題を回避しようとしているということです。彼らは更新情報を受け取っていると思っていますが、実際に物件をチェックすると、あなたが故意に嘘をついていたことがわかります。

ご想像のとおり、Cocoa にはそのようなハッキングをサポートするメカニズムがありません。それらは、オブジェクト指向プログラミングの構造全体を破壊する、非常に悪い習慣です。

講義はさておき、インスタンス変数に直接アクセスするカスタム セッターを作成できます。だから、例えば

- (void)setUserNameAndLieAboutItAsAShortSightedHack:(NSString *)newName
{
    _userName = newName;
}

システム レベルでは、キー値監視は、実際のセッターへの呼び出しを含み、外部で適切なオブザーバー呼び出しを行う新しいバージョンのプロパティ セッターを作成することによって実装されます。したがって、実際のセッターを回避すると、通知が回避されます。

于 2013-01-27T00:55:28.307 に答える