2014-07-07更新:苹果在iOS 8中全面使用instancetype代替id

Steven Fisher:只要一个类返回自身的实例,用instancetype就有好处。

@interface Foo:NSObject
- (id)initWithBar:(NSInteger)bar; // initializer
+ (id)fooWithBar:(NSInteger)bar; // convenience constructor
@end

对于简易构造函数(convenience constructor),应该总是用instancetype。编译器不会自动将id转化为instancetype。id是通用对象,但如果你用instancetype,编译器就知道方法返回什么类型的对象。

这个问题可不只有学术意义,比如,[[NSFileHandle fileHandleWithStandardOutput] writeData:formattedData]在Mac OS X(只在该OS版本)中会报错“Multiple methods named 'writeData:' found with mismatched result, parameter type or attributes.”原因是NSFileHandle和NSURLHandle都提供writeData:方法。由于[NSFileHandle fileHandleWithStandardOutput] 返回的类型是id,编译器并不确定请求了哪个类的writeData:方法。

你可以用

[(NSFileHandle *)[NSFileHandle fileHandleWithStandardOutput] writeData:formattedData];

NSFileHandle *fileHandle = [NSFileHandle fileHandleWithStandardOutput];
[fileHandle writeData:formattedData];

来绕过。

当然,更好的方法是声明fileHandleWithStandardOutput的返回类型为instancetype。(注意:这段样例代码在iOS中并不会报错,因为iOS中只有NSFileHandle提供writeData:方法。但length等方法则会,UILayoutSupport会返回CGFloat,而NSString则会返回NSUInteger)

initializer的情况更复杂,当你输入

- (id)initWithBar:(NSInteger)bar

编译器会假设你输入了

- (instancetype)initWithBar:(NSInteger)bar

对于ARC而言,这是必须的。Clang Language Extensions的相关结果类型(Related result types)也讲到了这一点。也许别人会据此告诉你不必使用instancetype,但我建议你用它。下面解释我为什么如此建议。

使用instancetype有三点好处:

1、明确性。代码只做你让它做的事,而不是其他。

2、程式化。你会养成好习惯,这些习惯在某些时候会很有用,而且肯定有用武之地。

3、一致性。让代码可读性更好。

明确性

用instancetype代替id作为返回值的确没有技术上的好处。但这是因为编译器自动将id转化成了instancetype。你以为init返回的值类型是id,其实编译器返回了instancetype。

这两行代码对于编译器来说是一样的:

- (id)initWithBar:(NSInteger)bar;
- (instancetype)initWithBar:(NSInteger)bar;

但在你眼里,这两行代码却不同。你不该学着忽视它。

模式化

在使用init等方法时的确没有区别,但在定义简易构造函数时就区别了。

这两行代码并不等价:

+ (id)fooWithBar:(NSInteger)bar;
+ (instancetype)fooWithBar:(NSInteger)bar;

如果用instancetype作为函数的返回类型,就不会出错。

一致性:

最后,想象把所有东西放到一起时的情景:你想要一个init方法和一个简易构造函数。

如果你用id来作为init函数的返回类型,最终代码如下:

- (id)initWithBar:(NSInteger)bar;
+ (instancetype)fooWithBar:(NSInteger)bar;

但如果你用instancetype,代码如下:

- (instancetype)initWithBar:(NSInteger)bar;
+ (instancetype)fooWithBar:(NSInteger)bar;

代码更加一致,可读性更强。它们返回相同的东西,这一点一目了然。

结论

除非你有意为旧编译器写代码,不然你在合适的时候都应该用instancetype。

在写一条返回id的消息前,问自己:这个类返回实例吗?如果返回,用instancetype。

肯定有需要返回id的时候,但你用instancetype的频率应该会更高。

本答案最后编辑于2013年7月12日

 

iOS 用instancetype代替id作返回类型有什么好处?的更多相关文章

  1. instancetype 与 id for Objective-C

    instancetype.id.NSObject的区别 - simalone   1.instancetype只能用于方法的返回类型,而id用处和NSObject *类似. 2.instancetyp ...

  2. [oc] instancetype vs id for Objective-C 【转】

    原贴地址:http://blog.csdn.net/lyy_whg/article/details/12846055 http://www.iwangke.me/2013/01/06/instance ...

  3. instancetype 与id

    1 .依照cocoa的命名规则,alloc,init这类方法,如果以id为返回类型,会返回类本身的类型,但类方法的返回类型,LLVM(clang)编译器无法判断,也就是说如果       用id作为返 ...

  4. ios instancetype 和 id 的异同

    1.0 相同点:都可以作为方法的返回类型 2.0 不同点: a.instancetype 可以返回和方法所在类相同类型的对象   id 只能返回未知类型的对象 b. instancetype 只能作为 ...

  5. ios instancetype与id区别

    我们都知道未知类型的的对象可以用id关键字表示,那为什么还会再有一个instancetype呢? instancetype能返回相关联的类型(使那些非关联返回类型的方法返回所在类的类型):而id 返回 ...

  6. instancetype VS id

    英文好的直接读下面链接的文章就好了: http://stackoverflow.com/questions/8972221/would-it-be-beneficial-to-begin-using- ...

  7. OC 类方法,对象方法,构造方法以及instancetype和id的异同

    OC 类方法,对象方法,构造方法以及instancetype和id的异同 类方法: 类方法是可以直接使用类的引用,不需要实例化就可以直接使用的方法.一般写一些工具方法. 类方法: 声明和实现的时候,以 ...

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

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

  9. instancetype、id、NSObject的联系和区别

    1.id和instancetype都能省去具体类型,提高代码的通用性.而NSObject *则没有这种功能. 2.instancetype只能用于方法的返回类型,而id用处和NSObject *类似. ...

随机推荐

  1. 5332盛照宗 如何获取新技能+c语言学习调查

    如何获取新技能+c语言学习调查 你有什么技能比大多人(超过90%以上)更好? 如果问我有没有什么技能比大多数人,并且是90%的人好,我还真不敢说有,因为世界上有70亿人,要比63亿人做的好才行啊.我也 ...

  2. 使用网易云音乐,丢掉QQ音乐吧

    我是一个听音乐的重度用户,基本上每天大约有三分之一的时间里我在使用网易云音乐去听音乐.包括工作写代码的时候,跑步的时候,去上班的途中我都去听.首先需要声明的是,在这里我不是故意的去抹黑其他的音乐产品, ...

  3. 【MPI学习5】MPI并行程序设计模式:组通信MPI程序设计

    相关章节:第13章组通信MPI程序设计. MPI组通信与点到点通信的一个重要区别就是:组通信需要特定组内所有成员参与,而点对点通信只涉及到发送方和接收方. 由于需要组内所有成员参与,因此也是一种比较复 ...

  4. 【逆向怎么玩】 动态调试一款牛逼C++ IDE实录

    声明 本篇只从逆向兴趣出发,研究其程序运行原理. CLion程序版权为jetBrains所有. 注册码授权为jetBrains及其付费用户所有. 不会释出任何完整的源代码. 涉及能直接推算出注册码的地 ...

  5. ARP 命令运行实现静态IP/MAC绑定

    公司网络出现本地无法连接,以前公司是分配的固定IP,结果还是无法连接网络,后来网管帮我设置了下,我也学习了下.解决办法如下: 1.首先以管理员身份运行CMD打开命令行程序 开始-程序-附件-命令提示符 ...

  6. 字符串string类型转换成DateTime或DateTime?类型

    常用的Convert.ToDateTime方法 //将含有正确日期格式的string类型转换成DateTime类型 string strDate = "2014-08-01"; D ...

  7. JavaScript表单处理(下)

    内容提纲: 1.文本框脚本 2.选择框脚本 发文不易,转载请亲注明链接出处,谢谢!   一.文本框脚本 在HTML中,有两种方式来表现文本框: 一种是单行文本框<input type=" ...

  8. Entity Framework with nolock. 允许脏读

    public static List<T> ToListReadUncommitted<T>(this IQueryable<T> query) { using ( ...

  9. Luncene 学习入门

    Lucene是apache组织的一个用java实现全文搜索引擎的开源项目. 其功能非常的强大,api也很简单.总得来说用Lucene来进行建立 和搜索和操作数据库是差不多的(有点像),Document ...

  10. Java虚拟机的功能

    1:通过ClassLoader寻找和装载class文件 2:解释字节码成为指令并执行,提供class文件的运行环境.即将字节码转换为不同OS下可执行的机器码指令. 3:进行垃圾回收. 4:提供与硬件交 ...