id
id 的定义如下:
/// Represents an instance of a class.
struct objc_object {
Class _Nonnull isa OBJC_ISA_AVAILABILITY;
};
typedef struct objc_object *id;
很明显,id 就是一个结构体指针,代表一个类的实例。而 NSObject 的定义为:
typedef struct objc_object NSObject;
所以,在 iOS 中,id 可以指代任何的实例对象。
这里需要注意的是实例,而不是类,因为类是 Class:
struct objc_class {
Class _Nonnull isa OBJC_ISA_AVAILABILITY;
#if !__OBJC2__
Class _Nullable super_class OBJC2_UNAVAILABLE;
const char * _Nonnull name OBJC2_UNAVAILABLE;
long version OBJC2_UNAVAILABLE;
long info OBJC2_UNAVAILABLE;
long instance_size OBJC2_UNAVAILABLE;
struct objc_ivar_list * _Nullable ivars OBJC2_UNAVAILABLE;
struct objc_method_list * _Nullable * _Nullable methodLists OBJC2_UNAVAILABLE;
struct objc_cache * _Nonnull cache OBJC2_UNAVAILABLE;
struct objc_protocol_list * _Nullable protocols OBJC2_UNAVAILABLE;
#endif
}
typedef struct objc_class *Class;
类用 objc_class 结构体表示,实例用 objc_object 表示;
instancetype
instancetype 是编译器特性,虽然转为 c++ 文件之后有 instancetype,但是在 objc4 源码中是看不到的:
- (instancetype)self;
- (id)self {
return self;
}
如上,最终还是变成了 id 类型。
总结
- 两者相同点都是可以指代 OC 中的对象实例;
- id 本质是结构体,所以表示不了具体的类型;
- instancetype 是编译器特性,可以推断出类型,所以可以方便开发者在书写代码时少写很多类型判断或者是类型强制转换的语句;
网友评论