1

这个观察者工作得很好

[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.'

但为什么?

4

1 回答 1

2

因为虽然contentOffset作为属性存在于您的类中,但它实际上是 a 的实例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风格。Cstruct早于 Objective-C 并且不实现 KVC。请记住,Objective-C 是建立在 C 之上的,因此 C 中的所有内容也都在 Objective-C 中,但反之则不适用。访问一个 Objective-C 类属性恰好与访问一个结构的成员具有相同的语法。

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

@property (nonatomic, assign) CGPoint contentOffset;

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

的声明CGPoint还确认它不是一个 Objective-C 类:

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

如您所见,CGPoint不是派生自NSObject.

于 2012-08-23T09:50:14.033 回答