博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
(转)Objective-C中的instancetype和id区别
阅读量:6305 次
发布时间:2019-06-22

本文共 5300 字,大约阅读时间需要 17 分钟。

有一个相同两个不同。相同Written by Mattt Thompson on Dec 10th, 2012Objective-C is a rapidly evolving language, in a way that you just don't see in established programming languages. ARC, object literals, subscripting, blocks: in the span of just three years, so much of how we program in Objective-C has been changed (for the better).All of this innovation is a result of Apple's philosophy of vertical integration. Just as Apple's investment in designing its own chipsets gave them leverage to compete aggressively with their mobile hardware, so too has their investment in LLVM allowed their software to keep pace.Clang developments range from the mundane to paradigm-changing, but telling the difference takes practice. Because we're talking about low-level language features, it's difficult to understand what implications they may have higher up with API design.One such example is instancetype, the subject of this week's article.In Objective-C, conventions aren't just a matter of coding best-practices, they are implicit instructions to the compiler.For example, alloc and init both have return types of id, yet in Xcode, the compiler makes all of the correct type checks. How is this possible?In Cocoa, there is a convention that methods with names like alloc, or init always return objects that are an instance of the receiver class. These methods are said to have a related result type.Class constructor methods, although they similarly return id, don't get the same type-checking benefit, because they don't follow that naming convention.You can try this out for yourself:[[[NSArray alloc] init] mediaPlaybackAllowsAirPlay]; // ❗ "No visible @interface for `NSArray` declares the selector `mediaPlaybackAllowsAirPlay`"[[NSArray array] mediaPlaybackAllowsAirPlay]; // (No error)Because alloc and init follow the naming convention for being a related result type, the correct type check against NSArray is performed. However, the equivalent class constructor array does not follow that convention, and is interpreted as id.id is useful for opting-out of type safety, but losing it when you do want it sucks.The alternative, of explicitly declaring the return type ((NSArray *) in the previous example) is a slight improvement, but is annoying to write, and doesn't play nicely with subclasses.This is where the compiler steps in to resolve this timeless edge case to the Objective-C type system:instancetype is a contextual keyword that can be used as a result type to signal that a method returns a related result type. For example:@interface Person+ (instancetype)personWithName:(NSString *)name;@end    instancetype, unlike id, can only be used as the result type in a method declaration.With instancetype, the compiler will correctly infer that the result of +personWithName: is an instance of a Person.Look for class constructors in Foundation to start using instancetype in the near future. New APIs, such as UICollectionViewLayoutAttributes are using instancetype already.下面的翻译:原文地址:http://blog.csdn.net/wzzvictory/article/details/16994913一、什么是instancetypeinstancetype是clang 3.5开始,clang提供的一个关键字,表示某个方法返回的未知类型的Objective-C对象。我们都知道未知类型的的对象可以用id关键字表示,那为什么还会再有一个instancetype呢?二、关联返回类型(related result types)根据Cocoa的命名规则,满足下述规则的方法:1、类方法中,以alloc或new开头2、实例方法中,以autorelease,init,retain或self开头会返回一个方法所在类类型的对象,这些方法就被称为是关联返回类型的方法。换句话说,这些方法的返回结果以方法所在的类为类型,说的有点绕口,请看下面的例子:[objc] view plaincopy在CODE上查看代码片派生到我的代码片    @interface NSObject      + (id)alloc;      - (id)init;      @end            @interface NSArray : NSObject      @end  当我们使用如下方式初始化NSArray时:[objc] view plaincopy在CODE上查看代码片派生到我的代码片    NSArray *array = [[NSArray alloc] init];  按照Cocoa的命名规则,语句[NSArray alloc] 的类型就是NSArray*因为alloc的返回类型属于关联返回类型。同样,[[NSArray alloc]init] 的返回结果也是NSArray*。三、instancetype作用1、作用如果一个不是关联返回类型的方法,如下:[objc] view plaincopy在CODE上查看代码片派生到我的代码片    @interface NSArray      + (id)constructAnArray;      @end  当我们使用如下方式初始化NSArray时:[objc] view plaincopy在CODE上查看代码片派生到我的代码片    [NSArray constructAnArray];  根据Cocoa的方法命名规范,得到的返回类型就和方法声明的返回类型一样,是id。但是如果使用instancetype作为返回类型,如下:[objc] view plaincopy在CODE上查看代码片派生到我的代码片    @interface NSArray      + (instancetype)constructAnArray;      @end  当使用相同方式初始化NSArray时:[objc] view plaincopy在CODE上查看代码片派生到我的代码片    [NSArray constructAnArray];  得到的返回类型和方法所在类的类型相同,是NSArray*!总结一下,instancetype的作用,就是使那些非关联返回类型的方法返回所在类的类型!2、好处能够确定对象的类型,能够帮助编译器更好的为我们定位代码书写问题,比如:[objc] view plaincopy在CODE上查看代码片派生到我的代码片    [[[NSArray alloc] init] mediaPlaybackAllowsAirPlay]; //  "No visible @interface for `NSArray` declares the selector `mediaPlaybackAllowsAirPlay`"            [[NSArray array] mediaPlaybackAllowsAirPlay]; // (No error)  上例中第一行代码,由于[[NSArray alloc]init]的结果是NSArray*,这样编译器就能够根据返回的数据类型检测出NSArray是否实现mediaPlaybackAllowsAirPlay方法。有利于开发者在编译阶段发现错误。第二行代码,由于array不属于关联返回类型方法,[NSArray array]返回的是id类型,编译器不知道id类型的对象是否实现了mediaPlaybackAllowsAirPlay方法,也就不能够替开发者及时发现错误。四、instancetype和id的异同1、相同点都可以作为方法的返回类型2、不同点①instancetype可以返回和方法所在类相同类型的对象,id只能返回未知类型的对象;②instancetype只能作为返回值,不能像id那样作为参数,比如下面的写法:[objc] view plaincopy在CODE上查看代码片派生到我的代码片    //err,expected a type      - (void)setValue:(instancetype)value      {          //do something      }  就是错的,应该写成:[objc] view plaincopy在CODE上查看代码片派生到我的代码片    - (void)setValue:(id)value      {          //do something      }

 

转载于:https://www.cnblogs.com/ak23173969/p/4408752.html

你可能感兴趣的文章
男人要内在美,更要外在美
查看>>
为什么要跟别人比?
查看>>
app启动白屏
查看>>
Oracle 提高查询性能(基础)
查看>>
学习知识应该像织网一样去学习——“网状学习法”
查看>>
Hadoop集群完全分布式安装
查看>>
QString,char,string之间赋值
查看>>
我的友情链接
查看>>
Nginx+mysql+php-fpm负载均衡配置实例
查看>>
shell脚本操作mysql数据库 (部份参考)
查看>>
MySql之基于ssl安全连接的主从复制
查看>>
informix的逻辑日志和物理日志分析
查看>>
VMware.Workstation Linux与windows实现文件夹共享
查看>>
ARM inlinehook小结
查看>>
wordpress admin https + nginx反向代理配置
查看>>
管理/var/spool/clientmqueue/下的大文件
查看>>
HTML学习笔记1—HTML基础
查看>>
mysql dba系统学习(20)mysql存储引擎MyISAM
查看>>
centos 5.5 64 php imagick 模块错误处理记录
查看>>
apache中文url日志分析--php十六进制字符串转换
查看>>