iOS开发笔记(十一):instancetype 和 id 类型的区别

本文探讨了instancetype和id这两种Objective-C中的通用指针类型之间的区别。instancetype仅可用作方法的返回类型,并能在编译时确定对象的真实类型,有助于及早发现错误。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

instancetype 和 id 都是万能指针,都可以指向一个对象,那么他们有什么区别呢。

1.instancetype 和 id 类型的区别:

  1. id 可以用来定义变量,可以作为返回值,可以作为形参。instancetype 只能用于作为返回值。
  2. id 在编译的时候不能判断对象的真实类型,instancetype 在编译的时候可以判断对象的真实类型。

第二点是我们讨论的重点,为此我们需要知道什么是关联返回类型

2.关联返回类型

根据 Cocoa 的命名规则,满足下述规则的方法会返回一个方法所在类类型的对象,被称为是关联返回类型的方法:

  1. 类方法中,以 alloc 或 new 开头
  2. 实例方法中,以 autorelease,init,retain 或 self 开头

换句话说,这些方法的返回结果以方法所在的类为类型,请看下面的例子:

NSArray *array = [[NSArray alloc] init];  
复制代码

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

3.instancetype 的作用

这里我创建了一个 Person 类,继承自 NSObject。

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

@interface Person : NSObject
+ (id)initObject;
@end
复制代码

那么我们初始化时:

[Person initObject];
复制代码

根据 Cocoa 的方法命名规范,得到的返回类型就和方法声明的返回类型一样,是 id。 但是如果使用 instancetype 作为返回类型,如下:

@interface Person : NSObject
+ (instancetype)initObject;
@end
复制代码

当使用相同方式初始化时,得到的返回类型和方法所在类的类型相同,是 Person*。 总结一下,instancetype 的作用,就是使那些非关联返回类型的方法返回所在类的类型。

4.instancetype 的好处

关联返回类型

首先我们调用如下方法:

[[[Person alloc] init] setFrame:CGRectMake(0, 0, 100, 100)];
复制代码

这里调用了 Person 中不存在的 setFrame: 方法,会报以下错误:

No visible @interface for 'Person' declares the selector 'setFrame:'
复制代码

由于 [[Person alloc] init] 返回的结果是 Person*,这样编译器就能够根据返回的数据类型检测出 Person 是否实现 setFrame: 方法,有利于开发者在编译阶段发现错误。

id

如果我实现 initObject 方法如下:

+ (id)initObject {
    return [[Person alloc] init];
}
复制代码

并且调用:

[[Person initObject] setFrame:CGRectMake(0, 0, 100, 100)];
复制代码

我们 Conmmand+B 编译一下,发现居然没有报错。原因是 initObject 不是关联返回类型方法,返回的是 id 类型,编译器不知道 id 类型的对象是否实现了 setFrame: 方法,在编译期没有检测 id 的真实类型,也就不能够替开发者及时发现错误。

instancetype

我们把返回类型改为 instancetype,再次调用 setFrame: 方法并编译,报了和第一次一样的错。在编译期检测了 instancetype 的真实类型。

所以,使用 instancetype 能够帮助我们在编译器及时发现一些错误。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值