Voloda2
Voloda2

Reputation: 12597

Error: this class is not key value coding-compliant for the key y

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

Answers (1)

dandan78
dandan78

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 structs 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

Related Questions