面试题答案
一键面试- 运行时情况:
- 由于Objective - C是动态类型语言,在运行时尝试插入一个不符合
MyProtocol
协议的对象作为值,不会直接引发编译错误。但是,当后续对该对象调用遵循MyProtocol
协议的方法时,如果该对象实际上并未实现这些方法,就会导致运行时错误,例如unrecognized selector sent to instance
错误。
- 由于Objective - C是动态类型语言,在运行时尝试插入一个不符合
- 编译期避免方法:
- 使用类型检查宏:在插入对象前,使用宏进行类型检查。例如,可以定义一个宏
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
,编译器可能会发出警告,虽然不能完全杜绝运行时错误,但能在一定程度上在编译期发现问题。