instancetype
在一些对象创建和初始化方法中,常看到方法返回类型为instancetype,比如NSObject中
+ (instancetype)new OBJC_SWIFT_UNAVAILABLE("use object initializers instead");
+ (instancetype)allocWithZone:(struct _NSZone *)zone OBJC_SWIFT_UNAVAILABLE("use object initializers instead");
+ (instancetype)alloc OBJC_SWIFT_UNAVAILABLE("use object initializers instead");
- (void)dealloc OBJC_SWIFT_UNAVAILABLE("use 'deinit' to define a de-initializer");
instancetype类型是调用该方法的类实例对象指针,因此instancetype类型是不确定的,动态变化的,运行时才能确定
@interface FBAnimal : NSObject
+ (instancetype)createAnimal;
- (instancetype)initAnimal;
@end
@implementation FBAnimal
+ (instancetype)createAnimal
{
return [[[self class] alloc] init];
}
- (instancetype)initAnimal
{
self = [super init];
return self;
}
@end
@interface FBDog : FBAnimal
@end
@implementation FBDog
@end
- (void)use_instancetype
{
id animal1 = [[FBAnimal alloc] init];
id animal2 = [[FBDog alloc] init];
id animal3 = [FBAnimal createAnimal];
id animal4 = [FBDog createAnimal];
id animal5 = [[FBAnimal alloc] initAnimal];
id animal6 = [[FBDog alloc] initAnimal];
NSLog(@"animal1 type: %s", class_getName(object_getClass(animal1)));
NSLog(@"animal2 type: %s", class_getName(object_getClass(animal2)));
NSLog(@"animal3 type: %s", class_getName(object_getClass(animal3)));
NSLog(@"animal4 type: %s", class_getName(object_getClass(animal4)));
NSLog(@"animal5 type: %s", class_getName(object_getClass(animal5)));
NSLog(@"animal6 type: %s", class_getName(object_getClass(animal6)));
}
output:
animal1 type: FBAnimal
animal2 type: FBDog
animal3 type: FBAnimal
animal4 type: FBDog
animal5 type: FBAnimal
animal6 type: FBDog
分析:
- alloc和init都是NSObject方法成员,返回类型都为instancetype(返回类型不确定),但在实际运行中分别为FBAnimal和FBDog调用,因此instancetype类型在运行中确定(返回类型分别为FBAnimal *和FBDog *)
- createAnimal和initAnimal都是FBAnimal方法成员,返回类型都为instancetype(返回类型不确定),但在实际运行中分别为FBAnimal和FBDog调用,因此instancetype类型在运行中确定(返回类型分别为FBAnimal *和FBDog *)
instancetype VS id
- instancetype类型表示不确定类型,运行时才能确定,运行时类型为调用该方法的类实例对象指针,id表示未知类型,类型是确定的,只是不知道,需进一步检测确定(上述animal1和animal2类型实际上已确定,只是不知道)
- instancetype类型是不确定类型,因此不能使用instancetype类型定义对象,instancetype类型只能用于方法成员返回类型,id类型是确定类型,表示objc_object指针类型,因此可用id类型定义对象,也可用id类型表示方法成员返回类型,id类型与oc类实例对象指针类型无异