在 Objective-C 中,为什么我们不能alloc
+init
or new
一个带有超类的基类对象,而我们可以使用超类的构造函数来初始化?
下面是一些代码:
s1
可以很轻松地创建。
NSMutableString *s1=[NSString string];
NSLog(@"%@",s1);
But s2
and s3
不能,并发出警告
Incompatible pointer types initializing 'SubClass *__strong' with an expression of type'BaseClass *'
NSMutableString *s2=[[NSString alloc] init];
NSLog(@"%@",s2);
NSMutableString *s3=[NSString new];
NSLog(@"%@",s3);
//here no warning.
id mem=[NSString alloc];
NSMutableString *s4=[mem init];
NSLog(@"%@",s4);
当我们将 alloc + init 分解为两个不同的语句时会发生什么?
答案可以在Objective-C 特性 http://clang.llvm.org/docs/LanguageExtensions.html#objective-c-featuresClang 3.3 文档的内容:
相关结果类型
根据 Cocoa 约定,具有特定名称的 Objective-C 方法
(“init”、“alloc”等)始终返回作为以下对象实例的对象
接收类的类型。据说此类方法具有“相关
结果类型”,这意味着发送到这些方法之一的消息将
与接收器类的实例具有相同的静态类型。
因此在
NSMutableString *s2 = [[NSString alloc] init];
右侧的类型实际上是NSString *
并不是id
,并将其分配给NSMutableString *
给出“不兼容的指针类型”警告。
另一方面,string
中的方法
NSMutableString *s1 = [NSString string];
没有“相关结果类型”,所以它只返回一个id
可以分配给NSMutableString *
.
仅当您使用时,将 alloc/init 分成单独的语句才会抑制警告id
作为中间类型。和NSString
or NSMutableString
您仍然收到警告:
NSString *tmp4 = [NSString alloc];
NSMutableString *s4 = [tmp4 init]; // <-- Warning here
NSMutableString *tmp5 = [NSString alloc]; // <-- Warning here
NSMutableString *s5 = [tmp5 init];
根据文档,如果方法的返回类型与其类的类型兼容并且满足以下条件,则该方法具有“相关结果类型”:
- 第一个单词是“alloc”或“new”,并且该方法是类方法,或者
- 第一个单词是“autorelease”、“init”、“retain”或“self”,该方法是实例方法。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)