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


    苹果在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?

    http://stackoverflow.com/questions/8972221/would-it-be-beneficial-to-begin-using-instancetype-instead-of-id

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

  • 相关阅读:
    查看Linux主机CPU及内存信息
    linux配置java环境变量(详细)
    Linux安装Redis
    Linux关闭防火墙
    使用Unison同步服务器目录
    Nginx详细配置
    CentOS命令行无线上网
    SQL Server查询所有的表名/空间占用量/行数
    CentOS安装Nginx安装详解
    基于 Django 2.0.4 的 djcelery 配置
  • 原文地址:https://www.cnblogs.com/zhangdashao/p/4506519.html
Copyright © 2020-2023  润新知