我正在做一些代码重构,但遇到一个问题,clang对这种情况没有任何警告:
@protocol CommonProtocol <NSObject>
- (void)common;
@end
=========
@interface Foo : NSObject <CommonProtocol>
- (void)foo;
@end
=========
@interface Bar : NSObject <CommonProtocol>
@end
=========
static id<CommonProtocol> getObject(void) {
return [Bar new];
}
Foo *casting = getObject(); /// ⚠️ there is no warning for this
[casting common];
[casting foo]; /// 💥 crash because the casting object do not respond to '-foo'
我认为类型'Foo *'和'id
注意:我试过'- everything'并且它仍然没有提示转换
这是Objective-C弱类型系统的自然结果,其中id
实际上可以被降级为任何类型的对象。用给定的协议专门化id
在这个方向上没有多大帮助,这就是为什么您很容易遇到意想不到的情况,就像当前的情况一样。
如果您想强制强制转换,一个解决方案是更改getObject
的签名以返回NSObject
而不是id
:
static NSObject<CommonProtocol> *getObject(void) {
return [Bar new];
}
有了这样的设置,朴素Foo *casting = getObject();
将生成一个明确的警告:
不兼容的指针类型用类型'NSObject *'的表达式初始化'Foo *'
,编写代码的人必须显式转换:
Foo *casting = (Foo *)getObject();