2012-02-27 55 views
3

問題來自我剛剛添加到this question的答案,但它不應該是一個重複的評論。Objective-C的動態綁定仍然困惑

@Bavarious對這個問題的答案對我來說很合理,但我仍然困惑爲什麼運行時無法將方法綁定到正確的對象上,即使對象是一個id?據我的理解,dynamic bindingdynamic typing是編譯器無法知道id背後的對象,但運行時應該知道這一點,並選擇正確的對象作爲消息的接收者。但爲什麼運行時無法做到這一點?

+0

注意:通過啓用'-Wstrict-selector-match',您可以讓編譯器發出警告(在某些情況下)。更好的是,消息類型限定的變量和參數,而不是純粹的'id's。 – justin 2012-02-27 05:52:34

回答

4

短的答案:C.

擴展:當編譯器生成的呼叫的方法,它實際上只是產生於C函數的調用 - )到objc_msgSend(或變體在其中 - 動態結合並調度該方法。

因爲C ABI運行「at the metal」(非常接近),傳遞參數和返回值的方式會根據類型發生顯着變化。例如,編譯器可以通過任何大小高達在寄存器32位(或在某些體系結構64位),但任何較大的將是在堆棧本身。

因此,編譯器不一定會發出一個通用的程序集來調用objc_msgSend() - 將方法調用 - 通過(id)作爲不同的簽名 - 將不同的參數類型分配給方法 - 可能需要不同的代碼生成。

現在,在技術上,編譯器可以爲許多情況生成相同的代碼,但它選擇採取保守的策略和抱怨。特別是,假設是,如果你有2點衝突的類型聲明,有可能是其他人,並提醒大家,具有不同的參數類型相同的名稱的方法是極其強烈反對。

+0

感謝您的迅速回復。現在我可以看到這一點,隨着衝突的類型聲明,編譯器可能會產生相同的代碼,這是曖昧的運行時間。 – neevek 2012-02-27 06:14:16

+1

樂意幫忙!如果你想學到很多東西就要多約objc_msgSend()和調度,我寫了一系列關於它的博客文章:http://www.friday.com/bbum/2009/12/18/objc_msgsend-part- 1路線的地圖/ – bbum 2012-02-27 06:52:40