id
id 是泛型类型变量。 id在编译时不会警告我们,但是如果有问题就会崩溃。
实例类型
instancetype 在编译时为我们进行类型检查以警告我们出现问题。
例如:
Animal.h
@interface Animal : NSObject
+ (id)giveMeAnimalA;
+ (instancetype)giveMeAnimalB;
+ (Animal *)giveMeAnimalC;
@end
Animal.m
@implementation Animal
+ (id)giveMeAnimalA {
return [[[self class] alloc] init];
}
+ (instancetype)giveMeAnimalB {
return [[[self class] alloc] init];
}
+ (Animal *)giveMeAnimalC {
return [[[self class] alloc] init];
}
@end
假设如果我们使用[[Animal giveMeAnimalA] count];
编译器不会警告我们,但我们会在运行时崩溃并出现异常,因为 Animal 没有 count 方法。
如果我们使用[[Animal giveMeAnimalB] count];
编译器会立即警告我们 Animal 没有 count 方法,我们可以避免在运行时崩溃。但是让我们的返回类型 Animal* 不是更简单吗?
假设我们有一个Dog 的子类Animal:
@interface Dog : Animal
- (void)makeSound;
@end
现在如果我们尝试调用
[[Dog giveMeAnimalC] makeSound];
这行不通,因为我们会返回一个没有 makeSound 方法的 Animal。