【问题标题】:How to add a method to an existing protocol in Cocoa?如何向 Cocoa 中的现有协议添加方法?
【发布时间】:2011-01-08 20:00:47
【问题描述】:

我想为现有协议扩展或添加另一种方法。虽然协议并不特别重要,但这是我正在尝试做的。

@protocol NSMatrixDelegate
- (void)myNewMethod:(id)sender;
@end

编译器警告我有相同协议的重复声明。我该如何正确地做到这一点?

谢谢。

【问题讨论】:

    标签: cocoa protocols


    【解决方案1】:

    您不能为协议定义类别。有两种解决方法:

    • 使用新的正式协议
    • 使用非正式协议和运行时检查

    正式协议

    定义一个新的正式协议如下所示:

    @protocol MyCustomMatrixDelegate <NSMatrixDelegate>
    
    - (void) myNewMethod:(id)sender;
    
    @end
    

    然后您将使您的自定义类符合&lt;MyCustomMatrixDelegate&gt; 而不是&lt;NSMatrixDelegate&gt;。如果您使用这种方法,有一些事情需要注意:[self delegate] 可能会被声明为id&lt;NSMatrixDelegate&gt;。这意味着你不能做[[self delegate] myNewMethod:obj],因为&lt;NSMatrixDelegate&gt;没有声明myNewMethod:方法。

    解决此问题的方法是通过强制转换重新键入delegate 对象。可能是这样的:

    - (id<MyCustomMatrixDelegate>) customDelegate {
      return (id<MyCustomMatrixDelegate>)[self delegate];
    }
    

    (但是,您可能需要先进行一些类型检查,例如:

    if ([[self delegate] conformsToProtocol:@protocol(MyCustomMatrixDelegate)]) {
      return (id<MyCustomMatrixDelegate>)[self delegate];
    }
    return nil;
    

    )

    然后你会这样做:

    [[self customDelegate] myNewMethod:obj];
    

    非正式协议

    对于NSObject 上的一个类别,这真是一个花哨的名字:

    @interface NSObject (MyCustomMatrixDelegate)
    
    - (void) myNewMethod:(id)sender;
    
    @end
    

    那么你只是不实现该方法。在您将发送该方法的类中,您会这样做:

    if ([[self delegate] respondsToSelector:@selector(myNewMethod:)]) {
      [[self delegate] myNewMethod:someSenderValue];
    }
    

    【讨论】:

    • 我尝试了正式协议方法。它可以工作,但是编译器警告说在协议中找不到自定义方法。我将正式协议添加到委托的接口中,并将委托的标头包含在我将委托消息发送到的对象的实现文件中。你知道为什么它还在抱怨吗?谢谢
    • 你太棒了。奇迹般有效。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-17
    • 1970-01-01
    • 1970-01-01
    • 2016-01-05
    • 1970-01-01
    相关资源
    最近更新 更多