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