我对一种奇怪的行为感到不安,如下例所示:
NSMutableArray *a1 = [[NSMutableArray alloc] init]; // fine
NSMutableArray *a2 = [NSMutableArray array];        // fine, too
// compiler reports incompatible pointer types; good:
NSMutableArray *a3 = [[NSArray alloc] init]; 
// compiler says nothing and is happy to assign this!
NSMutableArray *a4 = [NSArray array]; 
和类的init和array方法都返回。但是,当我调用这些方法时的行为根本不一样,clang 让我愉快地为变量赋值!NSArrayNSMutableArrayidNSArrayNSMutableArray
事实证明,clang 会自动将某些方法(包括initfamily)的返回类型更改为instancetype,从而能够在编译时确定[[NSArray alloc] init]返回的是 anNSArray *而不是 an NSMutableArray *。但是此检查根本不适用于该array方法。
为什么?像我上一个示例这样的行不应该至少产生一个警告吗?为什么不将所有这些方法都声明为返回instancetype?未来会改变吗?
更新
好消息:从 iOS 7 开始,[NSArray array]返回instancetype,因此对上述的赋值a4也会产生警告。其他方法喜欢arrayWithContentsOfFile:或arrayWithContentsOfURL仍然返回id,但是......</p>