2013-03-11 71 views
1

在Objective-C中,哪种编码更好?id myObj <MyProtocol> vs if([obj class] conformsToProtocol:@protocol(MyProtocol))

//版本#1

id obj<MyProtocol>; 
[obj myMessage]; 

//版本#2

id obj; 
    if([[obj class] conformsToProtocol:@protocol(MyProtocol)]) 
     [obj myMessage]; 

出于某种原因,我看到一个版本的示例代码,但对我来说第2版似乎更安全。 如果在运行时从一个不符合协议MyProtocol的通用标识中分配obj,会发生什么情况?

回答

9

首先是编译时检查。

第二个是运行时检查。但是协议一致性检查在特定时间(某些时候,需要注意的是,过早的优化以及所有这些)在某些地方有很大的开销。同样,协议支持@optional方法。

我建议在运行时使用编译时协议检查(即声明式,精确的接口和使用)以及respondsToSelector:。这将使得从@optional/@required过渡更容易,因为代码重构和respondsToSelector:是非常快。

+1

对选择器的响应也可以是开发的一个很好的补充。你创建了一个存根对象,并且在对选择器的响应错误的情况下有一些消息指出它是一个存根。这样,当你运行你的代码时,你会得到一个完整的东西列表。 – Bergasms 2013-03-11 23:32:44

1

两者兼具

id<MyProtocol> obj; 
if([[obj class] conformsToProtocol:@protocol(MyProtocol)]) 
{ 
    [obj myMessage]; 
} 

首先,变量的类型,告诉你打算用变量做什么编译器,但不保证该变量将实际持有你希望它是什么;第二,一致性检查,测试变量实际上持有你想要的。

1

由于objective-c在运行时绑定并且不是类型保存,所以同时执行这两个操作。正确的声明可以防止在编译时检测到的所有错误。出于充分的理由,其中大多数只是警告。运行时检查可以防止应用程序在您未引用您期望处理的事件时崩溃。