这位观察员运作良好
[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.'
但为什么呢?
答案 0 :(得分:2)
因为尽管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 struct
先于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
。