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

时间:2009-11-01 00:02:43

标签: objective-c cocoa protocols categories

如果我为类创建的类别添加的方法也符合协议规定的合同,我想将该类别标记为实现协议,从而向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 个答案:

答案 0 :(得分:13)

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

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

@implementation NSObject (SomeCategory_Impl)
  - (void)someDelegateMessage {}
@end

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

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

答案 1 :(得分:5)

您的协议声明是否包含NSObject协议?像这样:

@protocol SomeDelegate <NSObject>
...

这就是警告的来源,因为现在你的类别没有实现完整的协议。在刚刚输入的测试代码中,从协议中删除NSObject会删除编译器警告。

答案 2 :(得分:1)

如果您希望编译器关闭发送&lt; NSObject&gt;消息(重要的是你记得那是协议名称,而不是类名)然后只使用'id'变量,而不是'id',因为你明确地告诉编译器“这是一个只实现SomeDelegate协议的对象”

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