使用instancetype关键字作为返回类的实例的方法的返回类型(或该类的子类)。 这些方法包括alloc,init和类工厂方法。
在适当的位置使用instancetype而不是id可以提高Objective-C代码中的类型安全性。 例如,考虑下面的代码:
@interface MyObject : NSObject
+ (instancetype)factoryMethodA;
+ (id)factoryMethodB;
@end
@implementation MyObject
+ (instancetype)factoryMethodA { return [[[self class] alloc] init]; }
+ (id)factoryMethodB { return [[[self class] alloc] init]; }
@end
void doSomething() {
NSUInteger x, y;
x = [[MyObject factoryMethodA] count]; // Return type of +factoryMethodA is taken to be "MyObject *"
y = [[MyObject factoryMethodB] count]; // Return type of +factoryMethodB is "id"
}
分析:由于+ factoryMethodA方法的返回类型是instance,所以该消息表达式的类型为MyObject *。 由于MyObject没有-count方法,编译器会给出关于x行的警告:
main.m: ’MyObject’ may not respond to ‘count’
但是,因为返回类型在+ factoryMethodB方法的返回类型是id,编译器可能不给出关于y行的警告。 因为类型id的对象可以是任何类,并且因为可能存在某个类的某处有一个称为-count的方法,所以对于编译器,+ factoryMethodB的返回值可能实现该方法,所以不会给出警告。
在代码中,通常是init方法和类工厂方法中,将instancetype替换 id作为返回值类型。即使编译器自动转换以“alloc”,“init”或“new”开头的方法时,会有一个返回类型为id来返回instancetype,它不会转换其他方法。 Objective-C约定是为所有方法显式地写入instancetype。
结论:在 alloc 或者 init 中,我们强烈建议对所有返回类的实例的类方法和实例方法使用 instancetype 类型。 与id不同,instancetype关键字只能用作方法声明中的结果类型,而不是代码中的其他位置。