Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/116.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 分配的值相同时KVO触发_Ios_Cocoa_Key Value Observing - Fatal编程技术网

Ios 分配的值相同时KVO触发

Ios 分配的值相同时KVO触发,ios,cocoa,key-value-observing,Ios,Cocoa,Key Value Observing,如果我有如下财产 @property(assign, nonatomic) NSUInteger myValue; 并为其分配一个属性 self.myValue = 2; KVO将按预期开火。如果以后,我给它赋值相同的值 self.myValue = 2; KVO将再次开火。我曾假设,如果分配的值没有差异,Objective-C中的KVO将不会触发。看来我错了 是否有办法强制执行此默认行为,即在每次分配值时禁用KVO通知触发?我可以创建自己的访问器,但如果有很多属性需要更改,这可能需要大量

如果我有如下财产

@property(assign, nonatomic) NSUInteger myValue;
并为其分配一个属性

self.myValue = 2;
KVO将按预期开火。如果以后,我给它赋值相同的值

self.myValue = 2;
KVO将再次开火。我曾假设,如果分配的值没有差异,Objective-C中的KVO将不会触发。看来我错了

是否有办法强制执行此默认行为,即在每次分配值时禁用KVO通知触发?我可以创建自己的访问器,但如果有很多属性需要更改,这可能需要大量的工作

感谢您的回复。

KVO在调用setter(或其他mutator)时触发。没有额外的支票。一般来说,KVO非常轻量级,并且对性能非常敏感。由于不必要的更改通常很少,并且在大多数情况下对观察者无害,因此它们不包括检查旧值的额外开销。检查前一个值可能会很昂贵,例如,如果一个托管对象没有出现故障,那么只检查这种情况并不是默认行为


如果需要检查值是如何更改或没有更改的,您可以作为观察者通过传递选项
NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
来检查。然后,您将收到新值和旧值,您可以决定是否使用这些信息执行任何操作。但是,我在实践中发现,这不应该经常需要。

仅供参考,要将此逻辑添加到setter(使用手动更改通知),您可以使用:

- (void)setValue:(int)value
{
    if (_value == value) return;
    [self willChangeValueForKey:@"value"];
    _value = value;
    [self didChangeValueForKey:@"value"];
}

+ (BOOL)automaticallyNotifiesObserversOfValue { return NO; }

如果由于某种原因,只有当值更改时才会触发特定通知,这一点很重要,那么您需要编写自定义setter或在设置之前检查该值。ie
if(self.myValue!=2)self.myValue=2
。这是一个很好的问题,令人惊讶的是,苹果文档中从来没有明确说明这一点。是的,我已经在使用NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld值来解决这个问题。这没什么大不了的,我只是想知道是否有一种更简单的“内置”方式来做到这一点。干杯尼尔,我也有同样的想法。很高兴听到Rob确认系统确实发送了一条消息,即使刚刚设置的值相同。我想,在某些情况下,这里我的意思是纯粹为了性能(在极少数重要的情况下),最好在“发送端”上检查它是否是一个不变的值(因此,不要设置它),而不是检查“接收端”(例如,如果您有很多接收器,并且正在进行复杂的比较,比如字符串或其他)。再次感谢Rob Napier。这就是我所做的!这里记录了:这也是我所做的。对于性能和可维护性来说,比在潜在的大量接收器上重复检查更好。