【问题标题】:Error: this class is not key value coding-compliant for the key y错误:此类与键 y 的键值编码不兼容
【发布时间】:2012-08-18 19:24:45
【问题描述】:

这个观察者工作得很好

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

但这会产生错误。

[self.tableView addObserver:self forKeyPath:@"contentOffset.y" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];

 Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<NSConcreteValue 0x6e3eda0> valueForUndefinedKey:]: this class is not key value coding-compliant for the key y.'

但是为什么呢?

【问题讨论】:

    标签: ios key-value-observing


    【解决方案1】:

    因为虽然contentOffset 作为属性存在于您的类中,但它实际上是CGPoint 的一个实例,它只是一个常规的C 结构,而不是Objective-C 类,因此不符合KVC。

    在第二个示例中,您将其视为 Objective-C 类。

    更新

    这可能有点令人困惑,但回到你的例子:

    self.contentOffset       // contentOffset is a property of the current class
    self.contentOffset.y     // y is a member of the CGPoint structure of which contentOffset is an instance
    

    两者看起来一样,但一个是Objective-C风格,另一个是C风格。 C structs 早于 Objective-C 并且不实现 KVC。请记住,Objective-C 构建在 C 之上,因此 C 中的所有内容也都在 Objective-C 中,但反之则不适用。 访问一个 Objective-C 类属性恰好与访问一个结构的成员具有相同的语法。

    您可能正在继承UIScrollView,如果您检查适当的头文件,您可能会看到类似

    @property (nonatomic, assign) CGPoint contentOffset;
    

    assign 表示它是 C 数据类型。另请注意缺少指示指针的*

    CGPoint的声明也证实了它不是一个Objective-C类:

    struct CGPoint {
      CGFloat x;
      CGFloat y;
    };
    typedef struct CGPoint CGPoint;
    

    如您所见,CGPoint 不是从NSObject 派生的。

    【讨论】:

    • 据我了解,如果我们使用点语法,我们需要从 NSObject 继承 contentOffset。我说的对吗?
    • @Voloda2 KVO 依赖于在运行时创建 NSObject 的子类。这些子类覆盖属性的 setter 方法,并在调用 setter 时发布通知。 struct 没有 setter 方法,因此无法注入这些通知,这与直接修改实例变量的结果相同:在这种情况下将没有 KVO 通知
    猜你喜欢
    • 1970-01-01
    • 2014-05-17
    • 1970-01-01
    • 2017-09-27
    • 2017-12-15
    • 1970-01-01
    • 2015-08-27
    • 2011-03-17
    • 2012-09-24
    相关资源
    最近更新 更多