我只是想更深入地了解Objective C。
为什么我必须在通话前进行投射以避免警告?这对编译器来说不是小菜一碟吗?我是否缺少任何动态方面?
if ([a.class conformsToProtocol:@protocol(P1)])
{
[(id<P1>)a p1Message];
}
我的意思是,我从 C/C++ 的角度理解它,但毕竟我使用的是 Objective C 编译器而且我不喜欢强制转换。:)
我只是想更深入地了解Objective C。
为什么我必须在通话前进行投射以避免警告?这对编译器来说不是小菜一碟吗?我是否缺少任何动态方面?
if ([a.class conformsToProtocol:@protocol(P1)])
{
[(id<P1>)a p1Message];
}
我的意思是,我从 C/C++ 的角度理解它,但毕竟我使用的是 Objective C 编译器而且我不喜欢强制转换。:)
如果a
是在编译时将自己声明为实现的特定类型,P1
那么您不需要强制转换。
如果a
是类型,id
那么只有当返回类型不明确并且您实际使用它,或者它有参数时,您才需要强制转换。这通常意味着方法名称有多个方法签名,p1Message
因此编译器不知道期望哪个。
如果a
是某种类型,它没有将自己声明为实现,P1
那么——除非它单独(并重复地)声明p1Message
——你会收到一个警告,因为你正在调用一个对象可能没有实现的方法。
如果我不得不猜测,可能a
被声明为类型id
而不是id <P1>
(这对于代表来说更正常)并且您有多个p1Message
s 飞来飞去。您也可以主动加入演员表,因为有一天您可能有多个具有相同名称的不同消息,并且可能实现的其他人p1Message
不必知道项目中有人使用该方法名称的所有其他地方。
编译器不能从conformsToProtocol:
检查中推断出调用是安全的,p1Message
因为它是一个动态运行时。您可能conformsToProtocol:
在编译时或运行时替换了不同的实现,这意味着假设编译器知道它的作用是不安全的。该调用将像任何其他调用一样被动态调度。