消息傳遞
I’m sorry that I long ago coined the term “objects” for this topic because it gets many people to focus on the lesser idea. The big idea is “messaging” – that is what the kernal[sic] of Smalltalk is all about... The key in making great and growable systems is much more to design how its modules communicate rather than what their internal properties and behaviors should be.
Alan Kay 曾多次強調 Smalltalk 的核心不是面向對象,面向對象只是 the lesser ideas,消息傳遞才是 the big idea。
在編譯時你寫的 Objective-C 函數調用的語法都會被翻譯成一個 C 的函數調用 - objc_msgSend()
[array insertObject:foo atIndex:5];
objc_msgSend(array, @selector(insertObject:atIndex:), foo, 5);
當 objc_msgSend被執行后:
- 首先,obj會通過isa指針找到自己的class;
- 通過class中method list 來找 foo;
- 如果沒有找到foo,就繼續往它自己的superclass中找;
- 找到foo的話,就回去執行他實現的IMP.
但這種實現有個問題,效率低。但一個 class 往往只有 20% 的函數會被經常調用,可能占總調用次數的 80% 。每個消息都需要遍歷一次 objc_method_list 并不合理。如果把經常被調用的函數緩存下來,那可以大大提高函數查詢的效率。這也就是 objc_class 中另一個重要成員 objc_cache 做的事情 - 再找到 foo 之后,把 foo 的 method_name 作為 key ,method_imp 作為 value 給存起來。當再次收到 foo 消息的時候,可以直接在 cache 里找到,避免去遍歷 objc_method_list.