2011-05-10 116 views
3

我到處讀到Objective-C具有真正的動態綁定,其中C++只有Late綁定。不幸的是,沒有一本書能夠清楚地解釋它或者討論底層的實現。例如C++使用虛擬表。 Objective-C如何?延遲綁定vs動態綁定

回答

7

http://www.gnu.org/software/gnustep/resources/ObjCFun.html有一個很不錯的描述。

基本上動態綁定的意思是,在實際進行方法調用時,決定調用哪個方法。如果您願意,該方法可以在那時動態選擇。

編輯:這裏有更多的細節,以我的最佳理解。我不保證這是完全正確的,但它應該是正確的。 Objective C中的每個對象都是一個結構,其第一個成員名爲isa,是一個指向類的指針。每個類本身就是傳統奠定了作爲一個對象:

struct objc_class { 
    Class isa; 
    Class super_class; 
    const char *name; 
    long version; 
    long info; 
    long instance_size; 
    struct objc_ivar_list *ivars; 
    struct objc_method_list **methodLists; 
    struct objc_cache *cache; 
    struct objc_protocol_list *protocols; 
}; 

在運行時,這裏是僞代碼的一個方法查找發生了什麼:

Follow isa to find the class 
if implementation = class.lookup_method(method): 
    call implementation 
else if get_implementation = class.lookup_method(forwardInvocation): 
    implementation = get_implementation(method) 
    if implementation: 
     call implementation 
    else: 
     raise runtime error 
else: 
    raise runtime error 

而且這是如何lookup_method工作?

def lookup_method (class, method): 
    if method in class.objc_cache: 
     return implementation from objc_cache 
    else if method in class.objc_method_list: 
     cache implementation from objc_method_list 
     return implementation 
    else if implementation = class.super_class.lookup_method(method): 
     cache implementation 
     return implementation 
    else: 
     return null 

爲了迴應這個明顯的問題,是的,這比C++的虛擬錶慢得多。根據基準,約三分之一的速度。每一個客觀的C文本都緊隨其後,在現實世界中,方法查找速度幾乎不是瓶頸。

這比C的方法查找靈活得多。例如,您可以使用forwardInvocation使無法識別的方法轉到您在變量中擁有的對象。這種委派可以在不知道該對象的類型在運行時會被使用的情況下完成,或者它將支持哪些方法。您也可以將方法添加到類中 - 即使在運行時也是如此 - 無需訪問源代碼。對類和方法也有豐富的運行時反省。

明顯的缺點是,任何C++程序員都會在上下跳動,因爲你已經拋棄了編譯時類型檢查的任何希望。

這是否解釋了差異,並給你足夠的細節來了解正在發生的事情?

+0

你能舉個例子嗎?你的答案與任何教科書一樣模糊 – 2011-05-10 05:21:08

+0

@ vinod-james:我已經添加了很多關於實際使用機制的細節。 – btilly 2011-05-10 07:20:31

0

實際上,動態綁定和後期綁定都是相同的。在我們有靜態綁定或早期綁定,它檢查在編譯時發生的問題(有關變量,表達式等的錯誤),這些信息存儲在一個v-表(虛擬方法表)中。後期綁定所做的只是將方法與v表中的方法綁定在一起。