Objective c 为什么gcc会警告与'self=[super initDesignatedInit]不兼容的结构赋值';调用派生类?
我在Objective-C中设置了以下基类/派生类:Objective c 为什么gcc会警告与'self=[super initDesignatedInit]不兼容的结构赋值';调用派生类?,objective-c,gcc,warnings,Objective C,Gcc,Warnings,我在Objective-C中设置了以下基类/派生类: @interface ASCIICodeBase : NSObject { @protected char code_[4]; } - (Base *)initWithASCIICode:(const char *)code; @end @implementation ASCIICodeBase - (ASCIICodeBase *)initWithCode:(const char *)code len:(size_t)len {
@interface ASCIICodeBase : NSObject {
@protected
char code_[4];
}
- (Base *)initWithASCIICode:(const char *)code;
@end
@implementation ASCIICodeBase
- (ASCIICodeBase *)initWithCode:(const char *)code len:(size_t)len {
if (len == 0 || len > 3) {
return nil;
}
if (self = [super init]) {
memset(code_, 0, 4);
strncpy(code_, code, 3);
}
return self;
}
@end
@interface CountryCode : ASCIICodeBase
- (CountryCode *)initWithCode:(const char *)code;
@end
@implementation CountryCode
- (CountryCode *)initWithCode:(const char *)code {
size_t len = strlen(code);
if (len != 2) {
return nil;
}
self = [super initWithCode:code len:len]; // here
return self;
}
@end
在标有“here”的行中,我收到以下gcc警告:
警告:不兼容的Objective-C类型分配“struct ASCIICodeBase*”,应为“struct CurrencyCode*”
此代码是否有问题,或者我是否应该使用
asciocodebase
返回id
?或者在“here”行上使用强制转换?您应该将返回值强制转换为(CountryCode*)。该方法返回类型为asciocodebase*
的值,该值比CountryCode*
因此:
但是您真正应该做的是将返回类型设置为(id)
。在Objective-C中通常就是这样做的。使用(id)
作为返回值类型
Objective-C不支持协变声明。考虑:
@interface NSArray:NSObject
+ (id) array;
@end
现在,您可以在NSArray
和NSMutableArray
上调用+array
。前者返回一个不可变数组,后者返回一个可变数组。由于Objective-C缺少协变声明支持,如果将上述声明声明为返回(NSArray*)
,则子类方法的客户端将必须强制转换为`(NSMutableArray*)。丑陋、脆弱且容易出错。因此,使用泛型类型通常是最简单的解决方案
所以。。。如果要声明一个返回特定类实例的方法,请显式地执行typecast。如果您正在声明一个将被重写的方法,并且该重写可能返回子类,并且它返回子类的事实将向客户端公开,那么请使用(id)
指定的初始值设定者的工作方式相同。-init*
方法可能返回几乎任何类型的实例,这取决于实现的上下文(当然)。因此,初始化方法的返回类型是协变的,因此,您需要使用(id)
作为返回类型
不需要提交bug——已经有几个bug了
请注意,LLVM现在有一个
instancetype
关键字,可以在上述声明中代替id
。这意味着“此方法返回一个实例,该实例通过了调用它的类的isKindOfClass:
测试”,实际上。我不知道。当你参加StackOverflow时,我想你必须习惯这些懦夫式的否决票。是的,为什么这会被否决?这就是警告出现的原因。人们很奇怪。今天,用CLAN,您可能应该使用<代码> StaseCythype < /Cult>返回类型而不是<代码> ID>代码>(虽然不是所有其他的构造函数类方法)。我期待C++中使用的协变返回类型支持。(id)对于这样的基类消息是这样的。为什么这些“自动释放构造函数”和朋友不应该使用instancetype
而不是id
?顺便说一句,现在clang似乎支持目标C的协变返回类型。谢谢@Jean Philippellet——这是正确的。当我写上述内容时,它没有。
@interface NSArray:NSObject
+ (id) array;
@end