使用id作为返回类型
@interface BaseClass : NSObject
@end
@implementation BaseClass
@end
@interface SubClass1 : BaseClass
@end
@implementation SubClass1
@end
@interface SubClass2 : BaseClass
@end
@implementation SubClass2
@end
@implementation BaseClass
+ (id)createInstanceWithCondition:(BOOL)condition {
if (condition) {
return [[SubClass1 alloc] init];
} else {
return [[SubClass2 alloc] init];
}
}
@end
使用instancetype作为返回类型
@implementation BaseClass
+ (instancetype)createInstanceWithCondition:(BOOL)condition {
if (condition) {
return [[SubClass1 alloc] init];
} else {
return [[SubClass2 alloc] init];
}
}
@end
id和instancetype优缺点及问题阐述
- id优点:
- 通用性:id可以指向任何Objective - C对象类型,非常灵活,适用于返回类型不明确或者需要返回不同类型对象的情况。
- 兼容性:在早期Objective - C版本中,instancetype未引入时,id是处理此类需求的主要方式,所以具有很好的向后兼容性。
- id缺点:
- 类型检查不严格:编译器无法准确推断返回对象的真实类型,在调用返回对象的方法时,编译器不会进行严格的类型检查,可能导致运行时错误。例如,如果返回的是SubClass1对象,但开发者误当作SubClass2对象调用其特有的方法,编译器不会报错,但运行时会崩溃。
- 代码可读性稍差:从返回类型上无法直观了解实际返回对象的类型,增加了阅读和维护代码的难度。
- instancetype优点:
- 类型安全:编译器可以根据调用者的类型来推断返回对象的类型,提供更严格的类型检查,减少运行时错误。例如,如果在SubClass1的子类中调用
createInstanceWithCondition:
方法,编译器会推断返回的是SubClass1子类的实例,调用SubClass1子类特有的方法时,编译器会进行类型检查。
- 代码可读性好:表示返回类型与调用者所属类类型相关,从返回类型上可以更清晰地了解返回对象与类的关系,提高代码可读性。
- instancetype缺点:
- 局限性:只能用于实例方法和类方法的返回类型,不能像id一样作为变量类型使用。例如不能声明
id myObject;
,但不能声明instancetype myObject;
。
- 继承体系复杂性:在非常复杂的继承体系中,如果涉及到多重继承、类别(Category)等复杂情况,编译器对instancetype的类型推断可能会变得复杂甚至出现意外情况,需要开发者更加小心处理。