如何避免部分基类中的"不完整实现"警告

gar*_*ph0 14 oop coding-style objective-c

我已经创建了一个我的类需要实现的协议,然后将一些常见的功能分解到基类中,所以我这样做了:

@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
Run Code Online (Sandbox Code Playgroud)

这样在我的代码中我使用通用id <MyProtocol>.

代码可以工作(只要不直接使用Base),但编译器在Base的实现结束时会发出警告:

Incomplete implementation of class Base

有没有办法避免这种警告,或者更好的是,在Objc中获得这种部分实现的抽象基类行为的更合适的方法?

mip*_*adi 12

你可以想象做这样的事情:

@implementation Base

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

@end
Run Code Online (Sandbox Code Playgroud)

这样,您就有了一个实现,但默认情况下会引发异常.但是,如果派生类意外调用[super bar]或未覆盖bar,则不会引发异常.如果这不是您想要的,您可以将其缩短为:

@implementation Base

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

@end
Run Code Online (Sandbox Code Playgroud)

在这种情况下,即使子类调用[super bar]或不覆盖,也会引发异常bar.


Jac*_*kin 9

在协议定义中,您需要在@optional关键字下声明方法.

您的代码应如下所示:

@protocol MyProtocol

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

@end
Run Code Online (Sandbox Code Playgroud)

在SO上看到这个问题.