二、CLASS消息機制 參考文檔Cocoa深刻檢出消息機制
1,首先去該類的方法 cache 中查找,若是找到了就返回它;
2,若是沒有找到,就去該類的方法列表中查找。若是在該類的方法列表中找到了,則將 IMP 返回,並將它加入cache中緩存起來。根據最近使用原則,這個方法再次調用的可能性很大,緩存起來能夠節省下次調用再次查找的開銷。
3,若是在該類的方法列表中沒找到對應的 IMP,在經過該類結構中的 super_class指針在其父類結構的方法列表中去查找,直到在某個父類的方法列表中找到對應的IMP,返回它,並加入cache中;
4,若是在自身以及全部父類的方法列表中都沒有找到對應的 IMP,則看是否是能夠進行動態方法決議;
5,若是動態方法決議沒能解決問題,進入消息轉發流程c++
1、runtime
1. 傳統的面向過程的語言開發,例如c語言。實現c語言編譯器很簡單,只要按照語法規則實現一個LALR語法分析器就能夠了,編譯器優化是很是難的topic,不在這裏討論範圍內,忽略。 這裏咱們實現了編譯器其中最最基礎和原始的目標之一就是把一份代碼裏的函數名稱,轉化成一個相對內存地址,把調用這個函數的語句轉換成一個jmp跳轉指令。在程序開始運行時候,調用語句能夠正確跳轉到對應的函數地址。 這樣很好,也很直白, 太死板。everything is per-determined
2. 咱們但願靈活,因而須要開發面向對象的語言,例如c++。 c++在c的基礎上增長了類的部分。但這到底意味着什麼呢?咱們在寫它的編譯器要如何考慮呢?其實,就是讓編譯器多繞個彎,在嚴格的c編譯器上增長一層類處理的機制,把一個函數限制在它處在的class環境裏,每次請求一個函數調用,先找到它的對象, 其類型,返回值,參數等等,肯定了這些後再jmp跳轉到須要的函數。這樣不少程序增長了靈活性一樣一個函數調用會根據請求參數和類的環境返回徹底不一樣的結果。增長類機制後,就模擬了現實世界的抽象模式,不一樣的對象有不一樣的屬性和方法。一樣的方法,不一樣的類有不一樣的行爲! 這裏你們就能夠看到做爲一個編譯器開發者都作了哪些進一步的思考。可是。。。仍是死板, 咱們仍然叫c++是static language。
3. 但願更加靈活! 因而咱們徹底把上面哪一個類的實現部分抽象出來,作成一套完整運行階段的檢測環境。此次再寫編譯器甚至保留部分代碼裏的sytax名稱,名稱錯誤檢測,runtime環境註冊全部全局的類,函數,變量等等信息等等,咱們能夠無限的爲這個層增長必要的功能。調用函數時候,會先從這個運行時環境裏檢測因此可能的參數再作jmp跳轉,這就是runtime。編譯器開發起來比上面更加彎彎繞。可是這個層極大增長了程序的靈活性。 例如當調用一個函數時候,前2種語言,頗有可能一個jmp到了一個非法地址致使程序crash, 可是在這個層次裏面,runtime就過濾掉了這些可能性。 這就是爲何dynamic langauge更增強壯。 由於編譯器和runtime環境開發人員已經幫你處理了這些問題。緩存