Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 为什么gcc会警告与'self=[super initDesignatedInit]不兼容的结构赋值';调用派生类?_Objective C_Gcc_Warnings - Fatal编程技术网

Objective c 为什么gcc会警告与'self=[super initDesignatedInit]不兼容的结构赋值';调用派生类?

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 {

我在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 {
  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