代码之家  ›  专栏  ›  技术社区  ›  Justin Searls

类别可以同时实现协议吗?

  •  27
  • Justin Searls  · 技术社区  · 15 年前

    如果我为一个类创建的一个类别添加了一些方法,这些方法也实现了一个协议所规定的契约,那么我想将该类别标记为实现该协议,从而向obj-c预处理器指示该类也有效地实现了该协议。

    示例委托(为了清楚起见,感谢Ole!):

    @protocol SomeDelegate <NSObject>
      - (void)someDelegateMessage;
    @end
    

    示例类别:

    @interface NSObject (SomeCategory) <SomeDelegate>
      - (void)someDelegateMessage;    
    @end
    

    以及其他典型的实现

    @implement NSObject (SomeCategory)
      - (void)someDelegateMessage {}
    @end
    

    当我实际尝试此操作时,每个nsObject方法都会收到一个警告:

    警告:类别“someCategory”的实现不完整

    警告:找不到“-description”的方法定义

    警告:找不到“-IsEqual:”的方法定义

    警告:类别“someCategory”未完全实现“nsObject”协议

    如果我搬走就行了 <SomeDelegate> 从声明中,但当然nsObject不被认为是somedelegate

    3 回复  |  直到 10 年前
        1
  •  13
  •   Jens Ayton    10 年前

    解决方法是在没有实现的类别上声明协议,并在不同的类别中实现该方法,例如:

    @interface NSObject (SomeCategory) <SomeDelegate>
      - (void)someDelegateMessage;    
    @end
    
    @implementation NSObject (SomeCategory_Impl)
      - (void)someDelegateMessage {}
    @end
    

    如果你这样做, NSObject 将被视为符合 <SomeDelegate> 在编译时,运行时检查 someDelegateMessage 会成功的。然而, conformsToProtocol: 运行时检查将失败。

    当然,你应该 file a bug 请求在核心类上声明的方法不生成警告。

        2
  •  5
  •   Ole Begemann    15 年前

    你的协议声明可能包括 NSObject 协议?这样地:

    @protocol SomeDelegate <NSObject>
    ...
    

    这就是警告的来源,因为现在您的类别没有实现完整的协议。在我刚键入的测试代码中,删除 NSO对象 从协议中删除编译器警告。

        3
  •  1
  •   Jeff Laing    15 年前

    如果您希望编译器停止发送<nsObject>消息(重要的是要记住这是协议名,而不是类名),那么只需使用“id”变量,而不是“id”,因为您明确地告诉编译器“这是一个只实现somedelegate协议的对象”。

    或者,使用nsobject作为变量类型。