KVO:+ keyPathsForValuesAffecting< Key>不适用于NSObjectController(的子类) [英] KVO: +keyPathsForValuesAffecting<Key> doesn't work with (subclass of) NSObjectController

查看:108
本文介绍了KVO:+ keyPathsForValuesAffecting< Key>不适用于NSObjectController(的子类)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个KVO-able类(称为Observee),该类的affectedValue动态属性受affectingValue属性的影响.属性之间的依赖关系是通过实现+keyPathsForValuesAffectingAffectedValue方法定义的.

I have a KVO-able class (call it Observee), which affectedValue dynamic property is affected by affectingValue property. The dependency between the properties is defined by implementing +keyPathsForValuesAffectingAffectedValue method.

将值设置为affectingValue会通知affectedValue已按我的预期进行更改,除非OvserveeNSObjectController的子类.完整示例如下:

Setting a value to affectingValue notifies that affectedValue has changed as I expected, unless Ovservee is a subclass of NSObjectController. Full example follows:

@interface Observee : NSObject // or NSObjectController
@property (readonly, strong, nonatomic) id affectedValue;
@property (strong, nonatomic) id affectingValue;
@property (strong, nonatomic) NSArrayController *arrayController;
@end

@implementation Observee

@dynamic affectedValue;
- (id)affectedValue { return nil; }

+ (NSSet *)keyPathsForValuesAffectingAffectedValue {
  NSLog(@"keyPathsForValuesAffectingAffectedValue called");
  return [NSSet setWithObject:@"affectingValue"];
}

@end

@interface AppDelegate : NSObject <NSApplicationDelegate>
@property (strong, nonatomic) Observee *observee;
@end

@implementation AppDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)notification {
  self.observee = [[Observee alloc] init];
  [self.observee addObserver:self
                  forKeyPath:@"affectedValue"
                     options:NSKeyValueObservingOptionNew
                     context:NULL];
  NSLog(@"setting value to affectingValue");
  self.observee.affectingValue = @42;
}

- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary *)change
                       context:(void *)context {
  NSLog(@"affected key path = %@", keyPath);
}

@end

该示例工作正常,并且当Observee派生NSObject时,输出如下:

The example works fine and outputs as the following when Observee derives NSObject:

keyPathsForValuesAffectingAffectedValue called
setting value to affectingValue
affected key path = affectedValue

,但是当Observee派生NSObjectController时:

keyPathsForValuesAffectingAffectedValue called
setting value to affectingValue

(请注意,受影响的键路径=受影响的值"不存在.)

(note that "affected key path = affectedValue" is absent.)

在这两种情况下似乎都调用了keyPathsForValuesAffectingAffectedValue,但在后一种情况下却没有操作.

It seems that keyPathsForValuesAffectingAffectedValue is called in both cases but it is no-op in the latter.

此外,任何涉及NSObjectController(的子类)实例的键路径都不会影响其他键路径,例如:

Also, any key paths involving an instance of (subclass of) NSObjectController won't affect other key paths, such as:

@implementation SomeObject

// `someValue` won't be affected by `key.path.(snip).arrangedObjects`
+ (NSSet *)keyPathsForValuesAffectingSomeValue {
  return [NSSet setWithObject:@"key.path.involving.anNSArrayController.arrangedObjects"];
}

@end

在这种情况下如何声明关键路径之间的依赖关系?而且,为什么这整个事情都在发生?

How do I declare dependency between key paths in such cases? And, why is this whole thing happening?

(是的,我认识will/didChangeValueForKey:和朋友,但是用(另一个)设置器来封装所有影响键的路径很糟糕,我想避免这种情况.)

(Yes, I know about will/didChangeValueForKey: and friends, but wrapping up every affecting key path with a(nother) setter is terrible and I'd like to avoid it.)

推荐答案

NSController及其子类充满KVO黑魔法"和意外行为. (对于另一个示例,它们不尊重某些像NSKeyValueObservingOptionPrior这样的KVO选项.)如果您期望它们在KVO方面表现得像正常"对象,您将感到失望.它们的存在主要是为了支持可可结合.尽管乍一看绑定似乎只不过是KVO上的语法糖,但您可以看到(通过覆盖绑定对象的KVO支持方法并在其中设置断点),实际上,幕后花了很多功夫而不是简单的KVO观测.

NSController and its subclasses are full of KVO "black magic" and unexpected behaviors. (For another example, they don't respect certain KVO options like NSKeyValueObservingOptionPrior) You will be disappointed if you expect them to behave like "normal" objects with respect to KVO. They exist primarily to support Cocoa bindings. Although at first glance bindings may look like mere syntactic sugar on top of KVO, you can see (by overriding the KVO supporting methods of a bound-to object and setting breakpoints in them) that there's actually quite a bit more going on underneath the covers than a simple KVO observation.

向Apple提交错误,以增加他们修复(或至少记录)此类错误的可能性问题/行为.

Please file bugs with Apple to increase the likelihood that they'll fix (or at least document) these sorts of issues/behavior.

这篇关于KVO:+ keyPathsForValuesAffecting&lt; Key&gt;不适用于NSObjectController(的子类)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆