前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >id和instancetype的区别

id和instancetype的区别

作者头像
拉维
发布2019-11-12 16:55:52
1.5K0
发布2019-11-12 16:55:52
举报
文章被收录于专栏:iOS小生活iOS小生活

在开发当中,idinstancetype都是我们常见的类型,那么这两者有什么异同点呢?

相同点

我们知道,id实际上是指向objc_object结构体的指针,如下:

代码语言:javascript
复制
// A pointer to an instance of a class.
typedef struct objc_object *id;

也就是说,id类型的指针指向的是objc_object结构体,而objc_object结构体表示的就是类对象的实例对象,所以id可以表示所有类型的实例

instancetype也是一个可以指向所有类型的实例变量指针

不同点

我们在项目开发过程中,一般是覆写或者自定义一个类的实例对象的初始化方法的时候,才会用instancetype作为返回值类型,除此之外,在其他的地方根本不会用到instancetype。如下所示:

id既可以用在实例对象的初始化方法中表示返回类型,又可以表示各个方法中的参数实例的类型。也就是说, id 可以在任何地方使用用以表示各种未知类型的对象。

那么,为什么在实例对象的初始化方法中必须使用instancetype作为返回值类型呢?

我们来看一个例子。

新建一个Person类,然后定义其实例对象的初始化方法:

代码语言:javascript
复制
//Person.m

//id作为返回值类型
+ (id)person {
    return [[self alloc] init];
}

- (id)init {
    if (self = [super init]) {
        NSLog(@"id");
    }
    return self;
}

//instancetype作为返回值类型
+ (instancetype)person {
    return [[self alloc] init];
}

- (instancetype)init {
    if (self = [super init]) {
          NSLog(@"instancetype");
    }
    return self;
}

我们分别以 instancetype 和 id 作为返回值定义了初始化方法,然后在外界新建Person类的实例对象,分别编译:

代码语言:javascript
复制
/*
 id:编译通过,不会用警告
 instancetype:提示警告,接收对象的指针类型不匹配
 */
NSString * person = [Person person];

我们发现,使用NSString类型的指针指向Person类型的对象,当以id作为返回值类型的时候,编译通过,因为id可以指向任意类型的对象,id在运行期才会确定对象的真实类型;当以instancetype作为返回值类型的时候,编译期间会报警告,提示接收对象的指针类型不匹配,所以说instancetype比id多了一个在编译期通过编译器检测变量真实类型的功能,这可以提前暴露程序存在的风险

在编译期,编译器会检索对象指针instancetype的真实类型;而id类型的实例变量是在运行期才会确定其真实类型,所以编译期即便是类型不匹配也不会报警告。因此,使用instancetype作为返回值,实际上也是提高程序健壮性的一个手段

以上。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-11-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 iOS小生活 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档