面试题答案
一键面试确保类型安全
- 编译时检查:在Objective-C中使用泛型(自iOS 11和Xcode 9引入),通过在类、协议和方法声明中指定泛型类型参数,编译器可以在编译时检查类型。例如:
NSMutableArray<NSString *> *stringArray = [NSMutableArray array];
[stringArray addObject:@"Hello"]; // 正确
// [stringArray addObject:@(1)]; // 编译错误,类型不匹配
- 遵循类型约束:如果在协议中定义泛型,可以通过协议的一致性来确保类型安全。例如:
@protocol MyProtocol <NSObject>
@property (nonatomic, strong) id<MyProtocol> otherObject;
@end
@interface MyClass : NSObject <MyProtocol>
@property (nonatomic, strong) id<MyProtocol> otherObject;
@end
这里MyClass
遵循MyProtocol
,otherObject
属性的类型必须符合协议要求,从而保证类型安全。
性能优势
- 减少类型转换开销:传统非泛型方式下,从集合中取出对象时通常需要进行类型转换,如
NSArray
取出对象时要手动转换为特定类型。而使用泛型,编译器已知对象类型,无需运行时类型转换,提高性能。例如:
// 非泛型
NSArray *array = @[@"Hello", @"World"];
NSString *str = (NSString *)array[0];
// 泛型
NSArray<NSString *> *stringArray = @[@"Hello", @"World"];
NSString *str2 = stringArray[0]; // 无需类型转换
- 更好的代码可读性和维护性:虽然这不是直接的性能优势,但清晰的类型定义使代码更易读,减少因类型错误导致的潜在运行时问题,间接提升开发效率和维护性。
潜在性能瓶颈及优化
- 代码膨胀:泛型会导致编译器为不同类型参数生成重复代码,可能增加二进制文件大小。优化方法是尽量复用泛型代码,避免不必要的类型参数组合。例如,如果一个泛型类有多种类型参数,但某些功能是通用的,可以将通用部分提取到父类或独立方法中。
- 编译时间增加:由于编译器要为不同类型参数生成代码,编译时间可能延长。优化措施包括优化项目结构,减少不必要的泛型使用,对大型项目可以考虑增量编译等技术。