美文网首页
instancetype和id

instancetype和id

作者: 烟雨平生花飞舞 | 来源:发表于2018-05-30 23:46 被阅读0次

    一、什么是instancetype

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

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

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

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

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

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

    @interface NSObject

    + (id)alloc;

    - (id)init;

    @end

    @interface NSArray : NSObject

    @end

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

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

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

    三、instancetype作用

    1、作用

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

    @interface NSArray

    + (id)constructAnArray;

    @end

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

    [NSArray constructAnArray];

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

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

    @interface NSArray

    + (instancetype)constructAnArray;

    @end

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

    [NSArray constructAnArray];

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

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

    2、好处

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

    [[[NSArray alloc] init] mediaPlaybackAllowsAirPlay]; // "No visible @interface for `NSArray` declares the selector `mediaPlaybackAllowsAirPlay`"

    [[NSArray array] mediaPlaybackAllowsAirPlay]; // (No error)

    上例中第一行代码,由于[[NSArray alloc]init]的结果是NSArray*,这样编译器就能够根据返回的数据类型检测出NSArray是否实现mediaPlaybackAllowsAirPlay方法。有利于开发者在编译阶段发现错误。

    第二行代码,由于array不属于关联返回类型方法,[NSArray array]返回的是id类型,编译器不知道id类型的对象是否实现了mediaPlaybackAllowsAirPlay方法,也就不能够替开发者及时发现错误。

    返回值是instancetype类型时, Xcode编译器会随时检查 instancetype对应的真实类型,  如果发现接收对象的指针和真实类型不匹配是会给程序猿⚠️ ,  而id类型的只有在运行时才会检测到,不方便程序猿随时验证代码. 所以各有优劣, 应根据具体情况选择.

    不同点:

        1.id在编译的适合不能判断对象的真实类型,instancetype在编译的时候可以判断对象的真实类型

        2.id可以用来定义变量,可以作为返回值类型,可以作为形参类型;instancetype只能作为返回值类型

     注意:以后凡是自定义构造方法,返回值类型尽量使用instancetype,不要使用id


    id类型

    在Objective-C 中,id 类型是一个独特的数据类型。在概念上,类似Java 的Object 类,可以转换为任何数据类型。换句话说,id 类型的变量可以存放任何数据类型的对象。在内部处理上,这种类型被定义为指向对象的指针,实际上是一个指向这种对象的实例变量的指针。例如,下面定义了一个id类型的变量和返回一个id类型的方法:

    id anObject;  

    - (id) newObject: (int) type; 

    id 和void *并非完全一样。下面是id在objc.h中的定义:

    typedef struct objc_object {  

    Class isa;  

    } *id; 

    从上面看出,id 是指向struct objc_object 的一个指针。也就是说,id 是一个指向任何一个继承了Object(或者NSObject)类的对象。需要注意的是id 是一个指针,所以在使用id的时候不需要加星号,比如,

    id foo=nil; 

    上述语句定义了一个nil 指针,这个指针指向NSObject 的任意一个子类。而“id*foo=nil;”则定义了一个指针,这个指针指向另一个指针,被指向的这个指针指向NSObject的一个子类。

    在Objective-C中,id取代了int类型成为默认的数据类型(在C语言中,int是默认的函数返回值类型),关键字nil 被定义为空对象,也就是值为0 的对象。

    相关文章

      网友评论

          本文标题:instancetype和id

          本文链接:https://www.haomeiwen.com/subject/baxxsftx.html