[iOS]用instancetype代替id作返回类型有什么好处?(转)

著作权归作者所有。
商业转载请联系作者获得授权,非商业转载请注明出处。
作者:管策
链接:http://zhuanlan.zhihu.com/Foundation/19569459
来源:知乎

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日

原帖:objective c - Would it be beneficial to begin using instancetype instead of id?

注意:我也是刚入门而已,如果翻译的术语与通行术语不一致,敬请告知;如果选取的翻译内容有误或过时,敬请告知,谢谢。

时间: 2024-10-27 10:59:21

[iOS]用instancetype代替id作返回类型有什么好处?(转)的相关文章

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 co

instancetype 与 id for Objective-C

instancetype 与 id for Objective-C 分类: IOS2014-03-17 10:01 187人阅读 评论(0) 收藏 举报 instancetype vs id for Objective-C 新的LLVM编译器为我们带来了ARC, Object Literal and Scripting, Auto Synthesis等特性,同时也引入了instancetype关键字.instancetype用来表示Related Result Types(相关返回类型),那么它

对于Objective-C初学者而言,用instancetype和id来定义一个简易的构造函数,到底区别在哪?

在接触OC语言一段时间后,我们大家都知道未知类型的对象可以用 id 表示,那么 instancetype 是用来干嘛的? 1.instancetype的作用 就是使那些非关联返回类型的方法返回所在类的类型 2.使用instancetype好处 a.能够确定对象的类型,能够帮助编译器更好的为我们定位代码书写问题 b.编译器能够根据返回的数据类型检测是否实现方法,有利于开发者在编译阶段发现错误. 3.instancetype和id的异同 a.相同点 都可以作为方法的返回类型 b.不同点 ①insta

【转】iOS Objective-C中的instancetype和id关键字-关联返回类型和非关联返回类型

Objective-C中的instancetype和id关键字 分类: Objective-C2013-11-28 19:48 5421人阅读 评论(1) 收藏 举报 clangobjective-c编译器cocoainstancetype 目录(?)[+] Objective-C中的instancetype和id关键字 作者:wangzz 原文地址:http://blog.csdn.net/wzzvictory/article/details/16994913 转载请注明出处 如果觉得文章对你

iOS instancetype和id的区别

区别: 1>instancetype在类型表示上,跟id一样,可以表示任何对象类型 2>instancetype只能用在返回值类型上,不能像id一样用在参数类型上 3>instancetype比id多一个好处:编译器会检测instancetype的真实类型 第3点的解释: 在下面这种情况下 // Person.m文件里 + (id)person{ return [[self alloc] init]; } // mainViewController.m,下面这行代码,用字符串类型的指针指

iOS instancetype 跟 id 的区别

instancetype:在类型表示上,跟id一样,可以表示任何数据类型; instancetype只能用在返回值类型上,不能像id一样用在参数类型上; instancetype比id多一个好处:编译器会检测instancetype的真实类型.

ios instancetype 和 id 的异同

1.0 相同点:都可以作为方法的返回类型 2.0 不同点: a.instancetype 可以返回和方法所在类相同类型的对象   id 只能返回未知类型的对象 b. instancetype 只能作为返回值,不能像id 那样作为参数 在实际开发中,尽量使用 instancetype (当使用继承时,父类指向子类,相当有用)

【iOS入门】instancetype和id的区别

区别1: 在ARC(Auto Reference Count)环境下: instancetype用来在编译期确定实例的类型,而使用id的话,编译器不检查类型, 运行时检查类型. 在MRC(Manual Reference Count)环境下: instancetype和id一样,不做具体类型检查 区别2: id可以作为方法的参数,但instancetype不可以 instancetype只适用于初始化方法和便利构造器的返回值类型 作者:三木成森链接:https://www.jianshu.com

instancetype VS id

英文好的直接读下面链接的文章就好了: http://stackoverflow.com/questions/8972221/would-it-be-beneficial-to-begin-using-instancetype-instead-of-id https://developer.apple.com/library/ios/releasenotes/ObjectiveC/ModernizationObjC/AdoptingModernObjective-C/AdoptingModernO