使用KVO和自定义键

时间:2014-05-06 01:02:39

标签: ios objective-c

我很好奇,但可以使用自定义键(以及手动更改通知)实现KVO吗?

例如,我可以像这样注册:

[myObject addObserver:self forKeyPath:@"My custom string" options:0 context:nil];

并发出如下更改通知:

[self willChangeValueForKey:@"My custom string"];
// do something
[self didChangeValueForKey:@"My custom string"];

我在一个小测试应用程序中尝试了这个并且它可以工作,但我很好奇是否有人在其中使用了这个或看到过的值。

3 个答案:

答案 0 :(得分:1)

我同意,如果密钥与某个属性不对应,则您不应该使用KVO。但是,应该注意,属性不需要实例变量甚至访问器。您可以使用符合键值编码的方法完全实现动态属性。但是,只有使用KVC才能访问此类属性(例如-valueForKey[Path]:-setValue:forKey[Path]:)。

例如,如果实现-valueForUndefinedKey:,则可以检查密钥,如果它与动态或虚拟属性的名称匹配(使用您需要的任何条件),则可以返回适当的值。同样,如果您实现-setValue:forUndefinedKey:,则可以使该属性可写。

对于这种情况,您不必发出手动KVO更改通知。当你拨打-setValue:forKey[Path]:时,KVC会自动发出这些信息。但是,如果您更改了一些有效更改属性值的内部状态,则必须自行发出更改通知。

答案 1 :(得分:1)

如果您的目标只是收到某些事件的通知,最好只将自定义事件发布到NSNotificationCenter并注册。

如果您要为某些自定义属性实现KVO,那么您确实希望确保自定义属性为KVO Compliant,其中包括它应符合KVC标准。正如文档所说:

  

为了使特定属性符合KVO标准,班级必须确保以下内容:

     
      
  • 该类必须是符合该属性的键值编码,如“Ensuring KVC Compliance”中所述。

         

    KVO支持与KVC相同的数据类型。

  •   
  • 该类会为该属性发出KVO更改通知。

  •   
  • 相关密钥已正确注册(请参阅“Registering Dependent Keys”)。

  •   
     

有两种技术可确保发出更改通知。 NSObject提供自动支持,默认情况下,对于符合键值编码的类的所有属性都可以使用。通常,如果您遵循标准的Cocoa编码和命名约定,则可以使用自动更改通知 - 您不必编写任何其他代码。

     

手动更改通知可以在何时发出通知,并需要额外的编码。您可以通过实现类方法automaticallyNotifiesObserversForKey:来控制子类属性的自动通知。

简而言之,与willChangeValueForKeydidChangeValueForKey相比,KVO涉及的内容要多得多。


我建议您完全实现KVO(如果您只是合成标准属性,则完全符合KVO / KVC标准是非常容易的;如果您想手动完成它会稍微复杂一点),或者不要完全使用KVO,并使用其他接口,例如通知中心:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didReceiveNotification:) name:kMyNotificationKey object:nil];

使用像:

这样的处理程序
- (void)didReceiveNotification:(NSNotification *)notification
{
    // do whatever you want here
}

通知发布时间:

[[NSNotificationCenter defaultCenter] postNotificationName:kMyNotificationKey object:nil];

答案 2 :(得分:-1)

我想你可以,但是你错误地使用了这种机制。

如果您使用的密钥与您正在更改的属性不匹配,则提供之前和之后的值信息的通知将无法正常工作。我认为CrimsonChris有正确的想法。如果您正在做的只是触发事件,请使用通知。这就是通知管理器的用途。