bastibe
bastibe

Reputation: 17189

Warning: MyClass:NSObject does not implement key value observing? How can that be?

I just recently resumed work on a Cocoa project that I left a few months ago. Cocoa is a strange beast if you have not been using it for a while.

Anyway, at some point the compiler started dropping warnings:

Incomplete implementation of class 'MyClass'
Method definition for '-addObserver:forKeyPath:options:context' not found
Method definition for '-removeObserver:forKeyPath:' not found
Class 'MyClass' does not fully implement the 'MyZoomScrollViewDataSource' protocol

But MyClass is derived from NSObject, which does in fact implement -addObserver:forKeyPath: and -removeObserver:forKeyPath:context:.

The protocol looks like this:

@protocol MyZoomScrollViewDataSource
    // The range of Data that should be shown. This corresponds to the horizontal  
    //   zoom and the scroll value of self.
    @property FRange selectionRange;

    // Also, make sure the dataSource is KVO compliant
    - (void)addObserver:(NSObject *)anObserver forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context;
    - (void)removeObserver:(NSObject *)anObserver forKeyPath:(NSString *)keyPath;
@end

The class looks like this:

@interface MyClass : NSObject <MyZoomScrollViewDataSource> {
    IBOutlet Outlets...
    variables...
}
@properties...
(IBAction)actions...
- methods...
@end

I guess my Cocoa skills are in deep need for a refresh. But still, these methods should be inherited from NSObject, so how can MyClass not implement these methods?

Upvotes: 0

Views: 599

Answers (4)

bastibe
bastibe

Reputation: 17189

One possible solution to this is to explicitly add those functions to the class. This seems rather hackish to me. I would gladly use a cleaner way to do this if there is one.

@implementation MyClass

- (void)addObserver:(NSObject *)anObserver forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context {
    [super addObserver:anObserver forKeyPath:keyPath options:options context:context];
}

- (void)removeObserver:(NSObject *)anObserver forKeyPath:(NSString *)keyPath {
    [super removeObserver:anObserver forKeyPath:keyPath];
}

@end

The strangest thing is: This works not only with super, it works with self, too! Consider my mind blown. What the heck?

Upvotes: 1

user557219
user557219

Reputation:

You should be able to avoid those warnings by using the -Wno-protocol compiler option:

If a class is declared to implement a protocol, a warning is issued for every method in the protocol that is not implemented by the class. The default behavior is to issue a warning for every method not explicitly implemented in the class, even if a method implementation is inherited from the superclass. If you use the -Wno-protocol option, then methods inherited from the superclass are considered to be implemented, and no warning is issued for them.

Upvotes: 2

sidyll
sidyll

Reputation: 59277

The answer is in the question!

The compiler warning:

-addObserver:forKeyPath:
-removeObserver:forKeyPath:options:context:

The protocol:

-addObserver:forKeyPath:options:context:
-removeObserver:forKeyPath:

The second looks better.

Upvotes: 3

Abizern
Abizern

Reputation: 150565

Actually I was hasty with my answer.

Why are you declaring the KVO methods in the protocol. NSObject already implements a basic version of them?

Upvotes: 0

Related Questions