作者:韩俊强
转载请注明出处
一、什么是instancetype

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

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

根据Cocoa的命名规则,满足下述规则的方法:

1、类方法中,以alloc或new开头

2、实例方法中,以autorelease,init,retain或self开头

会返回一个方法所在类类型的对象,这些方法就被称为是关联返回类型的方法。换句话说,这些方法的返回结果以方法所在的类为类型,说的有点绕口,请看下面的例子:

  1. @interface NSObject
  2. + (id)alloc;
  3. - (id)init;
  4. @end
  5. @interface NSArray : NSObject
  6. @end

当我们使用如下方式初始化NSArray时:

NSArray *array = [[NSArray alloc] init];

当我们使用如下方式初始化NSArray时:

  1. NSArray *array = [[NSArray alloc] init];

按照Cocoa的命名规则,语句[NSArray alloc] 的类型就是NSArray*因为alloc的返回类型属于关联返回类型。同样,[[NSArray alloc]init] 的返回结果也是NSArray*。

三、instancetype作用

1、作用

如果一个不是关联返回类型的方法,如下:

  1. @interface NSArray
  2. + (id)constructAnArray;
  3. @end

当我们使用如下方式初始化NSArray时:

  1. [NSArray constructAnArray];

根据Cocoa的方法命名规范,得到的返回类型就和方法声明的返回类型一样,是id。

但是如果使用instancetype作为返回类型,如下:

  1. @interface NSArray
  2. + (instancetype)constructAnArray;
  3. @end

当使用相同方式初始化NSArray时:

  1. [NSArray constructAnArray];

得到的返回类型和方法所在类的类型相同,是NSArray*!

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

2、好处

能够确定对象的类型,能够帮助编译器更好的为我们定位代码书写问题,比如:

  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那样作为参数,比如下面的写法:

  1. //err,expected a type
  2. - (void)setValue:(instancetype)value
  3. {
  4. //do something
  5. }

就是错的,应该写成:

  1. - (void)setValue:(id)value
  2. {
  3. //do something
  4. }

五、参考

1、http://nshipster.com/instancetype/

2、http://clang.llvm.org/docs/LanguageExtensions.html#objective-c-features

Objective-C中的instancetype和id…的更多相关文章

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

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

  2. Objective-C中的instancetype和id关键字(转)

    转自:Objective-C中的instancetype和id关键字 一.什么是instancetype 同id一样,都是表示未知类型的的对象. 二.关联返回类型(related result typ ...

  3. Objective-C中的instancetype和id区别

    目录(?)[-] 有一个相同两个不同相同 Written by Mattt Thompson on Dec 10th 2012 一什么是instancetype 二关联返回类型related resu ...

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

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

  5. 【转】Objective-C中的instancetype和id关键字

    原文:http://blog.csdn.net/wzzvictory/article/details/16994913 一.什么是instancetype instancetype是clang 3.5 ...

  6. Objective-C中的instancetype与id的区别

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

  7. 理解Objective C 中id

    什么是id,与void *的区别 id在Objective C中是一个类型,一个complier所认可的Objective C类型,跟void *是不一样的,比如一个 id userName, 和vo ...

  8. Objective-C中instancetype和id的区别

    要区分instancetype和id,首先要弄清楚什么是关联返回类型(Related Result Type). 关联返回类型即一个方法的返回类型就是调用这个方法的调用者的类型.具有下列条件的方法具有 ...

  9. OC中instancetype与id的区别

    1.在ARC环境下: instancetype用来在编译期确定实例的类型,而使用id的话,编译器不检查类型, 运行时检查类型. 2.在MRC环境下: instancetype和id一样,不做具体类型检 ...

随机推荐

  1. Android 学习笔记二 自定义按钮形状 颜色 点击渐变

    问题:自定义按钮的颜色 形状弧度  渐变效果 1.新建自定义属性button_login.xml (借鉴某大神) <?xml version="1.0" encoding=& ...

  2. python转lua最容易掉进去的坑--作用域

    你以为会依次打印2,4,8吗? 错. 2,2,2 value = 1 for i=1,3 do local value = value*2 print(value) end 你以为打印1吗?,错,输出 ...

  3. 《An Introduction to Signal Smoothing》译文

    最近在做数据平滑相关的工作,正好读到该篇博客,感觉不错,就翻译了一下.原链接:An Introduction to Signal Smoothing 信号平滑简介 噪声无处不在,不管是在采集手机游戏的 ...

  4. Swift中方法(method)所谓的lazy绑定简介

    我们知道在ruby之类的动态语言中对象方法可以先从类中预先抽取,然后再应用到某个具体对象上.这称为无绑定的method对象,也可以叫做lazy绑定. 下面举个例子: irb(main):004:0&g ...

  5. 使用maven执行单元测试总结

    maven本身没有单元测试框架,但是maven的default生命周期的test阶段绑定了maven-surefire-plugin插件,该插件可以调用Junit3.Junit4.TestNG等Jav ...

  6. Linux 高性能服务器编程——I/O复用

    问题聚焦:     前篇提到了I/O处理单元的四种I/O模型.     本篇详细介绍实现这些I/O模型所用到的相关技术.     核心思想:I/O复用 使用情景: 客户端程序要同时处理多个socket ...

  7. Dynamics CRM2016 Web API之更新记录的单个属性字段值

    在web api中提供了对单个属性的更新接口,这和查询中查询单个属性类似,对这个接口我个人也是比较喜欢的. var id = "{D1E50347-86EB-E511-9414-ADA183 ...

  8. SceneKit:简单的3D游戏场景搭建

    SceneKit是Apple用来开发休闲3D游戏的框架,不同于底层的OpenGL库,你仅仅需要很少的代码就可以快速看到实际的3D场景效果.下面简单的聊聊搭建一个3D游戏场景需要做的事情. 首先你必须用 ...

  9. SpriteKit给游戏弹跳角色添加一个高度标示器

    这是一个类似于跳跃涂鸦的小游戏,主角不断吃能量球得到跳跃能量向更高的地方跳跃,如果图中碰到黑洞就挂了- 在游戏调试过程中如果能实时知道主角的高度就好了,这将有助于程序猿动态的判断游戏胜败逻辑. 你可以 ...

  10. 全文检索 Lucene(3)

    看完前两篇博客之后,想必大家对于Lucene的使用都有了一个比较清晰的认识了.如果对Lucene的知识点还是有点模糊的话,个人建议还是先看看这两篇文章. 全文检索 Lucene(1) 全文检索 Luc ...