Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid "incomplete implementation" warning in partial base class

I have created a protocol that my classes need to implement, and then factored out some common functionality into a base class, so I did this:

@protocol MyProtocol
- (void) foo;
- (void) bar;
@end

@interface Base <MyProtocol>
@end

@interface Derived_1 : Base
@end

@interface Derived_2 : Base
@end

@implementation Base
- (void) foo{
//something foo
}
@end

@implementation Derived_1
- (void) bar{
//something bar 1
}
@end

@implementation Derived_2
- (void) bar{
//something bar 2
}
@end

In this way in my code I use a generic id<MyProtocol>.

The code works (as long as Base is not used directly) but the compiler chokes at the end of the implementation of Base with a warning:

Incomplete implementation of class Base

Is there a way to avoid this warning or, even better, a more proper way to obtain this partially implemented abstract base class behavior in Objc?

like image 751
garph0 Avatar asked May 18 '10 04:05

garph0


2 Answers

You could conceivably do something like this:

@implementation Base

- (void)bar
{
    if ([self class] == [Base class]) {
        [self doesNotRecognizeSelector:_cmd];
    }
}

@end

That way, you have an implementation, but by default it raises an exception. However, if a derived class accidentally calls [super bar] or does not override bar, then the exception won't be raised. If that's not what you want, you could just shorten it to:

@implementation Base

- (void)bar
{
    [self doesNotRecognizeSelector:_cmd];
}

@end

In which case, an exception will be raised, even if a subclass calls [super bar] or does not override bar.

like image 161
mipadi Avatar answered Sep 19 '22 13:09

mipadi


In your protocol definition, you need to declare your methods under the @optional keyword.

Your code should look like this:

@protocol MyProtocol

@optional
- (void) foo;
- (void) bar;

@end

See this question on SO.

like image 28
Jacob Relkin Avatar answered Sep 20 '22 13:09

Jacob Relkin