MST
星途 面试题库

面试题:Objective-C轻量级泛型在集合类中的复杂使用限制

考虑一个场景,有一个自定义类`MyContainer`,内部使用`NSDictionary`来存储数据,并且使用轻量级泛型来约束键值对类型,如`NSDictionary<NSString *, id<MyProtocol>>`。如果在运行时,尝试插入一个不符合`MyProtocol`协议的对象作为值,会发生什么情况?如何在编译期尽可能避免这种情况?
12.1万 热度难度
编程语言Objective-C

知识考点

AI 面试

面试题答案

一键面试
  1. 运行时情况
    • 由于Objective - C是动态类型语言,在运行时尝试插入一个不符合MyProtocol协议的对象作为值,不会直接引发编译错误。但是,当后续对该对象调用遵循MyProtocol协议的方法时,如果该对象实际上并未实现这些方法,就会导致运行时错误,例如unrecognized selector sent to instance错误。
  2. 编译期避免方法
    • 使用类型检查宏:在插入对象前,使用宏进行类型检查。例如,可以定义一个宏VALIDATE_OBJECT
#define VALIDATE_OBJECT(obj, protocol) \
(([obj conformsToProtocol:@protocol(protocol)])? YES : NO)

然后在插入对象到NSDictionary前,调用这个宏进行检查:

if (VALIDATE_OBJECT(newObject, MyProtocol)) {
    [myContainerDictionary setObject:newObject forKey:newKey];
} else {
    NSLog(@"对象不符合MyProtocol协议,不能插入");
}
  • 使用泛型约束并结合静态分析工具:在Xcode中,可以利用Clang静态分析工具,结合轻量级泛型约束来尽可能发现这种潜在问题。确保代码遵循正确的泛型类型约束,在编译时如果有明显的类型不匹配,静态分析工具可能会给出警告。例如,在声明和使用MyContainer类时,明确其内部NSDictionary的泛型类型,编译器可能会对不符合类型约束的赋值操作发出警告:
@interface MyContainer : NSObject
@property (nonatomic, strong) NSDictionary<NSString *, id<MyProtocol>> *myContainerDictionary;
@end

这样,在代码中如果尝试将不符合MyProtocol协议的对象赋值给myContainerDictionary,编译器可能会发出警告,虽然不能完全杜绝运行时错误,但能在一定程度上在编译期发现问题。