在我的项目中,我有3个课程,我们称之为Apple,Orange和Pear。
Apple和Orange都有代表属性 它们都在头文件中定义了名为AppleDelegate和OrangeDelegate的协议 它们每个都有具有相似签名的初始化器:
- (id)initWithDelegate:(id<AppleDelegate>)delegate
- (id)initWithDelegate:(id<OrangeDelegate>)delegate
Pear实现了OrangeDelegate,定义如下:
@interface Pear : NSObject <OrangeDelegate>
Inside Pear,我打了这个电话:
Orange *anOrange = [[[Orange alloc] initWithDelegate:self] autorelease];
这导致此编译器警告:
Class 'Pear' does not implement the 'AppleDelegate' protocol
在我看来,编译器无法识别初始化程序中的协议。换句话说,它只识别这两个签名:
- (id)initWithDelegate:(id)delegate
因为当我在Pear中的初始化程序中单击“跳转到定义”时,它会将这两个类作为选项。
除了重命名我的方法之外,有没有办法纠正这个警告?
答案 0 :(得分:3)
问题是'alloc'是一个从NSObject继承的方法,定义为返回类型'id'。以下是:
[Orange alloc]
评估“id”类型的对象。然后在该对象上调用initWithDelegate时,编译器不知道类型,在这种情况下猜测错误的类型。所以你可以用以下方法消除警告:
Orange *anOrange = [[(Orange *)[Orange alloc] initWithDelegate:self] autorelease];
所以,基本上,这是因为构造函数不是Objective-C中的语言级特性,只是一种约定。
编辑:见下文;我想另一种解决方案是添加:+ (Orange *)alloc;
到Orange,这不会比以前更复杂:
+ (Orange *)alloc
{
return [super alloc];
}
我想这部分是一个设计决策 - 类应该负责知道它们的构造函数方法可能与其他类的名称冲突,或者应该使用相同构造函数导入多个类定义的文件负责消除歧义。虽然语法的简单外观可能是关键。