Objective-C指向实现协议的类的指针

时间:2010-04-18 23:49:16

标签: objective-c polymorphism

我有三个实现相同协议的类,并且具有不实现协议的相同父类。通常我会将协议作为父类中的纯虚函数,但我找不到Objective-C方法来做到这一点。

我想通过在超类中声明纯虚函数然后让子元素实现这些函数来利用这些子类的多态性。然而,我发现这样做的唯一Objective-C方法是让每个孩子明确决定实现一个协议,当我这样做时,超类不知道孩子们将实现该协议,所以有编译时警告到处都是。

如果没有意义,可以使用一些伪代码:

@interface superclass: NSObject
{}

@interface child1: superclass<MyProtocol>
{}

@interface child2: superclass<MyProtocol>
{}

这些类的消费者:

@class child1
@class child2
@class superclass

@interface SomeViewController: UIViewController
{
    child1 *oneView;
    child2 *otherView;
    superclass *currentView;
}

-(void) someMethod
{
    [currentView protocolFunction];
}

我发现在Objective-C中执行纯虚函数的唯一好方法是将[self doesNotRecognizeSelector:_cmd];放在父类中,但这并不理想,因为它会导致运行时错误而不是编译时间。

4 个答案:

答案 0 :(得分:11)

Objective-C开发人员通常在这些情况下使用动态检查而不是编译时检查,因为语言和框架对它的支持非常好。例如,你可以像这样编写你的方法:

- (void)someMethod
{
    // See if the object in currentView conforms to MyProtocol
    //
    if ([currentView conformsToProtocol:@protocol(MyProtocol)])
    {
        // Cast currentView to the protocol, since we checked to make
        // sure it conforms to it. This keeps the compiler happy.
        //
        [(SuperClass<MyProtocol> *) currentView protocolMethod];
    }
}

答案 1 :(得分:5)

通过使superclass *currentView属性看起来像这样,我能够让编译器正确警告我:

@property (nonatomic, retain) superclass<MyProtocol> *currentView;

答案 2 :(得分:3)

或者您可以使用以下

if ([unknownObject conformsToProtocol:@protocol(MyProtocol)])
   [unknownObject performSelector:@selector(methodInProtocol)];
如果您只想抑制警告,请使用

而不是以下内容。

if ([unknownObject conformsToProtocol:@protocol(MyProtocol)])
   [unknownObject methodInProtocol];  // will cause warning

performSelector:仅在参数个数为零或一个时才起作用。使用NSInvocation可以实现更灵活的调用。

答案 3 :(得分:1)

就个人而言,我会在超类上实现协议,但是实现这样的方法:

- (id) myProtocolMethod {
  NSAssert(NO, [NSString stringWithFormat:@"-[%@ %@] must be overridden", NSStringFromClass([self class]), NSStringFromSelector(_cmd)]);
  return nil;
}

这样,如果你忘记在一个具体的子类中覆盖一个方法,那么它应该是显而易见的。