Reputation: 12597
This observer works well
[self.tableView addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];
But this one produce an error.
[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.'
But why?
Upvotes: 1
Views: 677
Reputation: 13854
Because although contentOffset
exists as a property in your class, it is in fact an instance of a CGPoint
, which is just a regular C structure, not an Objective-C class and hence is not KVC compliant.
In the second example you're treating it like an Objective-C class.
Update
It might be slightly confusing, but going back to your example:
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
The two look the same, but one is Objective-C style and the other is C-style. C struct
s predate Objective-C and do not implement KVC. Remember that Objective-C is built on top of C, so everything that is in C is also in Objective-C, but the reverse does not apply.
Accessing an Objective-C class property just happens to have the same syntax as accessing a member of a struct.
You're probably subclassing UIScrollView
and if you check the appropriate header file, you'll probably see something like
@property (nonatomic, assign) CGPoint contentOffset;
The assign
means it's a C data type. Also note the lack of a *
that would indicate a pointer.
The declaration of CGPoint
also confirms that it is not an Objective-C class:
struct CGPoint {
CGFloat x;
CGFloat y;
};
typedef struct CGPoint CGPoint;
As you can see, CGPoint
is not derived from NSObject
.
Upvotes: 2