2013-03-11 69 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在運行時綁定並且不是類型保存,所以同時執行這兩個操作。正確的聲明可以防止在編譯時檢測到的所有錯誤。出於充分的理由,其中大多數只是警告。運行時檢查可以防止應用程序在您未引用您期望處理的事件時崩潰。