iOS 用instancetype代替id作返回类型有什么好处?
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作返回类型有什么好处?的更多相关文章
- instancetype 与 id for Objective-C
instancetype.id.NSObject的区别 - simalone 1.instancetype只能用于方法的返回类型,而id用处和NSObject *类似. 2.instancetyp ...
- [oc] instancetype vs id for Objective-C 【转】
原贴地址:http://blog.csdn.net/lyy_whg/article/details/12846055 http://www.iwangke.me/2013/01/06/instance ...
- instancetype 与id
1 .依照cocoa的命名规则,alloc,init这类方法,如果以id为返回类型,会返回类本身的类型,但类方法的返回类型,LLVM(clang)编译器无法判断,也就是说如果 用id作为返 ...
- ios instancetype 和 id 的异同
1.0 相同点:都可以作为方法的返回类型 2.0 不同点: a.instancetype 可以返回和方法所在类相同类型的对象 id 只能返回未知类型的对象 b. instancetype 只能作为 ...
- ios instancetype与id区别
我们都知道未知类型的的对象可以用id关键字表示,那为什么还会再有一个instancetype呢? instancetype能返回相关联的类型(使那些非关联返回类型的方法返回所在类的类型):而id 返回 ...
- instancetype VS id
英文好的直接读下面链接的文章就好了: http://stackoverflow.com/questions/8972221/would-it-be-beneficial-to-begin-using- ...
- OC 类方法,对象方法,构造方法以及instancetype和id的异同
OC 类方法,对象方法,构造方法以及instancetype和id的异同 类方法: 类方法是可以直接使用类的引用,不需要实例化就可以直接使用的方法.一般写一些工具方法. 类方法: 声明和实现的时候,以 ...
- 转载:Objective-C中的 instancetype 和 id 关键字
Objective-C中的instancetype和id关键字 作者:wangzz 原文地址:http://blog.csdn.net/wzzvictory/article/details/16994 ...
- instancetype、id、NSObject的联系和区别
1.id和instancetype都能省去具体类型,提高代码的通用性.而NSObject *则没有这种功能. 2.instancetype只能用于方法的返回类型,而id用处和NSObject *类似. ...
随机推荐
- JS判断输入是否为整数和数字的正则表达式
"^\\d+$" //非负整数(正整数 + 0) "^[0-9]*[1-9][0-9]*$" //正整数 "^((-\\d+)|(0+))$" ...
- Asp.Net MVC 合并js或css请求
Step1:BundleConfig中注册 bundles.Add(new ScriptBundle("~/isValid").Include( "~/Scripts/ ...
- 运用Java对微信公众平台二次开发技术——开发者模式接入
当初我在这碰到了很多问题,市面上以及网络上的资料特别少,所以当初碰了很多壁,所以现在跟大家分享一下,如何用Java,对微信公众平台进行二次开发. 一.开发预备知识: 最基本的JavaSE与JavaWe ...
- http长链接与短链接
http://www.cnblogs.com/cswuyg/p/3653263.html keep-live模式 这个博客写的很全:http://www.cnblogs.com/skynet/arch ...
- setTimeout 0秒
我们通常知道常用setTimeout 0秒来解决动画或者一些效果的延迟问题:众所周知js是单线程,用0秒能把要执行的任务从队列中提出来.其实我也不太懂 有这个问题alert(1);setTimeout ...
- Boostrap(3)
常用标签 1.文字 p标签(段落) small标签(让文字呈现灰色) em标签(文字斜体) blokcquote标签(文字内容为引用时用该标签) class=”pull-right"右浮动 ...
- c# JD快速搜索工具,2015分析JD搜索报文,模拟请求搜索数据,快速定位宝贝排行位置。
分析JD搜索报文 搜索关键字 女装 第二页,分2次加载. rt=1&stop=1&click=&psort=&page=3http://search.jd.com/Se ...
- 复合sql
update select update bucp..Core_Flow_Opinion set useruid =(select user_uid from bua..bua_user b wher ...
- 验证xml是否有效于.dtd文件
<html> <head> <script language="javascript"> <!-- //加载解析器对象 var xmldo ...
- 【BZOJ】【1009】 【HNOI2008】GT考试
DP/KMP/矩阵乘法 好神的题啊……跪了跪了 $n\leq 10^9$是什么鬼……我们还是先不要考虑这个鬼畜的玩意了>_> 用类似数位DP的思路,我们可以想到一个DP方程:$f[i][j ...