如何在没有触发器KVO的情况下设置值

Leo*_*ang 4 objective-c key-value-observing

我使用以下代码在对象上添加KVO.

[self.model addObserver:self
             forKeyPath:@"userName"
                options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
                context:nil];
Run Code Online (Sandbox Code Playgroud)

现在我想设置userName,如下所示.是的,它会触发KVO.

self.model.userName = @"testUser";
Run Code Online (Sandbox Code Playgroud)

但是,我想在没有触发器KVO的情况下设置值.怎么做?有没有像下面这样的方法允许我这样做?

[self.model setValue:@"testUser" forKey:@"userName" isSilent:YES];
Run Code Online (Sandbox Code Playgroud)

Fru*_*eek 6

核心数据实现setPrimitiveValue:forKey:了允许您这样做.您可以在对象中实现相同的方法.

[self.model setPrimitiveValue:@"testUser" forKey:@"userName"];
Run Code Online (Sandbox Code Playgroud)

然而,当这样做时,它应该在聚合通知的上下文中,其中观察者最终通过手动willChangeValueForKey:和通知didChangeValueForKey:.


Tom*_*mmy 5

如果你想这样做,你的设计就会被打破.键值观察的关键是有人想知道字段何时发生变化,以便注册通知.符合键值观察的要点是,您要保持关于系统其余部分如何与您交互的选项.

听起来你正在做的是试图解决一些问题,你不希望有人因某种原因知道房产的真正价值.因此他们认为他们正在获得更新,但实际上如果他们要检查房产,那么事实证明你是故意撒谎.

正如您所期望的那样,Cocoa没有任何支持此类黑客攻击的机制.它们是非常糟糕的做法,打破了面向对象编程的整个结构.

另外,您可以编写一个直接转到实例变量的自定义setter.所以,例如

- (void)setUserNameAndLieAboutItAsAShortSightedHack:(NSString *)newName
{
    _userName = newName;
}
Run Code Online (Sandbox Code Playgroud)

在系统级别,通过创建属性setter的新版本来实现键值观察,该版本包含对真实setter的调用并在外部进行适当的观察者调用.因此避免使用真正的setter会避免通知.