1

我只是想更深入地了解Objective C。

为什么我必须在通话前进行投射以避免警告?这对编译器来说不是小菜一碟吗?我是否缺少任何动态方面?

if ([a.class conformsToProtocol:@protocol(P1)])
{
  [(id<P1>)a p1Message];
}

我的意思是,我从 C/C++ 的角度理解它,但毕竟我使用的是 Objective C 编译器而且我不喜欢强制转换。:)

4

1 回答 1

1

如果a是在编译时将自己声明为实现的特定类型,P1那么您不需要强制转换。

如果a是类型,id那么只有当返回类型不明确并且您实际使用它,或者它有参数时,您才需要强制转换。这通常意味着方法名称有多个方法签名,p1Message因此编译器不知道期望哪个。

如果a是某种类型,它没有将自己声明为实现,P1那么——除非它单独(并重复地)声明p1Message——你会收到一个警告,因为你正在调用一个对象可能没有实现的方法。

如果我不得不猜测,可能a被声明为类型id而不是id <P1>(这对于代表来说更正常)并且您有多个p1Messages 飞来飞去。您也可以主动加入演员表,因为有一天您可能有多个具有相同名称的不同消息,并且可能实现的其他人p1Message不必知道项目中有人使用该方法名称的所有其他地方。

编译器不能从conformsToProtocol:检查中推断出调用是安全的,p1Message因为它是一个动态运行时。您可能conformsToProtocol:在编译时或运行时替换了不同的实现,这意味着假设编译器知道它的作用是不安全的。该调用将像任何其他调用一样被动态调度。

于 2012-09-26T19:29:36.750 回答