NSMutableArray *a1 = [[NSMutableArray alloc] init]; // fineNSMutableArray *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];
NSArray和NSMutableArray类的init和array方法都返回ID.但是,当我调用这些方法的行为根本不一样,cl ang ang ang happ happ happ happ an an an an!!!!!!!NSMutableArray变量!
事实证明,clang will automatically change the return type of some methods,including the init
family,to instancetype
,因此能够在编译时确定[[NSArray alloc] init]返回NSArray *而不是NSMutableArray *.但是这个检查根本不适用于数组方法.
为什么?不应该像我上一个例子那样产生至少一个警告?为什么这些方法不是声明为返回的类型?将来会改变吗?
更新
好消息:从iOS 7开始,[NSArray数组]返回实例类型,所以赋值给a4也会产生一个警告.其他方法,如arrayWithContentsOffile:或arrayWithContentsOfURL仍然返回ID,虽然…
解决方法But this check simply doesn’t work with the array method. Why?
正如您链接的文档描述的那样,这是因为-array不会产生可识别的相关结果类型. ObjC非常动态 – 编译器不能保证数组的结果类型.它使用某些方法做出这一假设,因为命名约定被很好地定义(例如,alloc,-init,new,-self等).所以这个实现只是采用命名约定.
编译器还会在您不希望的区域中验证一些命名约定:
@implementation NSArray (DEMO)- (ID)initStr{ return [Nsstring new]; // << warning. RE: init prefix}@end
Shouldn’t lines like my last example generate at least a warning? Why aren’t all these methods declared as returning instancetype? Will it change in the future?
一年前介绍的类型(从它的外观).一些API是几十年前写的.我怀疑它会发生 – 在时间上 – 因为(如果使用正确),它可以指出现有代码中的很多问题.当然,这些改变会破坏现有的构建(再次,如果在正确的地方声明,通常是很好的修正).
所以文件错误,给工具和库几年来更新.假设进行更改,可能会发生在主要的 *** 作系统更新.
如果它被启用了一段时间的可选警告(在系统标题的情况下),可能是最好的.当然,他们仍然可以使用旧的编译器向后兼容新的API.
而且,这个改变可以很容易地进行改造(不是早期的编译器会通过简单的typedef来理解ID和instancetype之间的语义差异). typedef的一个问题是它是一个全局声明 – 一个编译器可以将一个单词/修饰符/属性限制在给定的范围内,而不会通过添加一个全局typedef而造成模拟关键字的所有痛苦.苹果公司的GCC可能永远不会支持实体类型,所以将它引入苹果GCC的合法方式可能是一个全局的IDedef,这可能会导致一些人(如果采用该路由,没有语义的好处)的问题.请注意,苹果过去已经做出类似的突破性变化.
总结以上是内存溢出为你收集整理的objective-c – 在目标C中,为什么我允许将NSArray分配给NSMutableArray,而不会出现错误或警告?全部内容,希望文章能够帮你解决objective-c – 在目标C中,为什么我允许将NSArray分配给NSMutableArray,而不会出现错误或警告?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)