有一个相同两个不同。相同

Written by Mattt Thompson on Dec 10th, 2012

Objective-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

一、什么是instancetype

instancetype是clang 3.5开始,clang提供的一个关键字,表示某个方法返回的未知类型的Objective-C对象。我们都知道未知类型的的对象可以用id关键字表示,那为什么还会再有一个instancetype呢?

二、关联返回类型(related result types)

根据Cocoa的命名规则,满足下述规则的方法:1、类方法中,以alloc或new开头2、实例方法中,以autorelease,init,retain或self开头会返回一个方法所在类类型的对象,这些方法就被称为是关联返回类型的方法。换句话说,这些方法的返回结果以方法所在的类为类型,说的有点绕口,请看下面的例子:
[objc] view plaincopy
  1. @interface NSObject
  2. + (id)alloc;
  3. - (id)init;
  4. @end
  5. @interface NSArray : NSObject
  6. @end
当我们使用如下方式初始化NSArray时:
[objc] view plaincopy
  1. NSArray *array = [[NSArray alloc] init];
按照Cocoa的命名规则,语句[NSArray alloc] 的类型就是NSArray*因为alloc的返回类型属于关联返回类型。同样,[[NSArray alloc]init] 的返回结果也是NSArray*。

三、instancetype作用

1、作用

如果一个不是关联返回类型的方法,如下:
[objc] view plaincopy
  1. @interface NSArray
  2. + (id)constructAnArray;
  3. @end

当我们使用如下方式初始化NSArray时:
[objc] view plaincopy
  1. [NSArray constructAnArray];
根据Cocoa的方法命名规范,得到的返回类型就和方法声明的返回类型一样,是id。

但是如果使用instancetype作为返回类型,如下:
[objc] view plaincopy
  1. @interface NSArray
  2. + (instancetype)constructAnArray;
  3. @end
当使用相同方式初始化NSArray时:
[objc] view plaincopy
  1. [NSArray constructAnArray];
得到的返回类型和方法所在类的类型相同,是NSArray*!

总结一下,instancetype的作用,就是使那些非关联返回类型的方法返回所在类的类型!

2、好处

能够确定对象的类型,能够帮助编译器更好的为我们定位代码书写问题,比如:
[objc] view plaincopy
  1. [[[NSArray alloc] init] mediaPlaybackAllowsAirPlay]; //  "No visible @interface for `NSArray` declares the selector `mediaPlaybackAllowsAirPlay`"
  2. [[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
  1. //err,expected a type
  2. - (void)setValue:(instancetype)value
  3. {
  4. //do something
  5. }
就是错的,应该写成:
[objc] view plaincopy
  1. - (void)setValue:(id)value
  2. {
  3. //do something
  4. }

Objective-C中的instancetype和id区别相关推荐

  1. (转)Objective-C中的instancetype和id区别

    有一个相同两个不同.相同 Written by Mattt Thompson on Dec 10th, 2012Objective-C is a rapidly evolving language, ...

  2. 转载:Objective-C中的 instancetype 和 id 关键字

    Objective-C中的instancetype和id关键字 作者:wangzz 原文地址:http://blog.csdn.net/wzzvictory/article/details/16994 ...

  3. Objective-C中的instancetype和id关键字

    作者:wangzz 原文地址:http://blog.csdn.net/wzzvictory/article/details/16994913 转载请注明出处 如果觉得文章对你有所帮助,请通过留言或关 ...

  4. instancetype和id的区别

    一.什么是instancetype instancetype是clang 3.5开始,clang提供的一个关键字,表示某个方法返回的未知类型的Objective-C对象.我们都知道未知类型的的对象可以 ...

  5. mysql id in set_mysql数据库中find_in_set()和in()用法区别

    mysql数据库中find_in_set()和in()用法区别 (2015-07-19 08:30:21) 标签: mysql数据库 find_in_set 在mysql中in可以包括指定的数字,而f ...

  6. 关于instancetype代替id的使用区别

    使用instancetype有三点好处: 1.明确性.代码只做你让它做的事,而不是其他. 2.程式化.你会养成好习惯,这些习惯在某些时候会很有用,而且肯定有用武之地. 3.一致性.让代码可读性更好. ...

  7. html 中 标签里面的id 和 name 有什么区别?

    html 中 标签里面的id 和 name 有什么区别? id与name的作用,作为标签的标识符,基本上是一样的.name是老方法,id是在name基础上发明的,后来才有的. 一般来说,js中使用ID ...

  8. mysql''和null,mysql中NULL和null的区别

    接触php的web开发一段时间了,在进行数据库操作的时候经常会遇到一个问题,使得同一字段在页面显示时有3种类型NULL,null以及数字,当时的解决办法是将这一字段定义为varchar类型,在插入数据 ...

  9. 静态方法与非静态方法的区别_程序员必看之ThinkPHP5中model与Db的区别

    在ThinkPHP5的使用过程中,很多使用者刚接触到数据库操作时,不能很好调用相关的方法进行数据库的交互.下面就分享一下ThinkPHP5中Db与模型的区别 关于db与model的选择 使用DB方式是 ...

最新文章

  1. ActiveMQ 入门
  2. 计算机考研分数2019,2019考研分数线和国家线有什么关系
  3. python中iloc的详细用法_python选取特定列 pandas iloc,loc,icol的使用详解(列切片及行切片)...
  4. 【noi 2.6_2421】Exchange Rates(DP)
  5. jstree中文api文档_还在用 Swagger(丝袜哥)生成接口文档?我推荐你试试它。。。...
  6. .NET和JAVA的比较- 体系结构
  7. 斯坦福大学深度学习公开课cs231n学习笔记(7)神经网络防止数据过拟合:损失函数和正则化
  8. 面试题心得--spring注解的原理
  9. 密码学的基础:X.690和对应的BER CER DER编码
  10. 下等人薄情,中等人深情,上等人……
  11. 泛在传感器网络(Ubiquitous Sensor Network; USN)
  12. 《拆掉思维里的墙》的读后感作文900字
  13. 支付宝摇一摇红包脚本【Auto.js】
  14. uni-app 二维码扫描识别功能
  15. java研发网页数据采集
  16. 突发,阿里腾讯大规模裁员30%......
  17. 联想yoga11装linux,Yoga PC阻止用户安装Linux 联想:微软的锅feilianmeidong
  18. 使用Teigha.NET操作DWG基本配置
  19. 如何使用清源 CleanSource SCA 管理开源风险
  20. RHEL8 新特征及使用方法

热门文章

  1. 音视频开发系列(24)使用FFmpeg添加、删除、替换和提取视频中的音频
  2. 读《金刚经》学心态,读《易经》学生存,读《道德经》学生活
  3. jQuery带logo的网页二维码生成
  4. C#与Word文档的交互
  5. 【源码】锂电池模型、Simscape语言与Simulink优化设计
  6. Flutter环境搭建、运行gallary项目
  7. 2048网页版html项目报告,jQuery编写网页版2048小游戏
  8. 计算机组成原理实验第一章
  9. 自带设备(BYOD)能用零信任框架吗?
  10. 有些钱,即便不脏,但也有毒。