消息傳遞
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 曾多次強(qiáng)調(diào) Smalltalk 的核心不是面向?qū)ο?,面向?qū)ο笾皇?the lesser ideas,消息傳遞才是 the big idea。
在編譯時(shí)你寫(xiě)的 Objective-C 函數(shù)調(diào)用的語(yǔ)法都會(huì)被翻譯成一個(gè) C 的函數(shù)調(diào)用 - objc_msgSend()
[array insertObject:foo atIndex:5];
objc_msgSend(array, @selector(insertObject:atIndex:), foo, 5);
當(dāng) objc_msgSend被執(zhí)行后:
- 首先,obj會(huì)通過(guò)isa指針找到自己的class;
- 通過(guò)class中method list 來(lái)找 foo;
- 如果沒(méi)有找到foo,就繼續(xù)往它自己的superclass中找;
- 找到foo的話,就回去執(zhí)行他實(shí)現(xiàn)的IMP.
但這種實(shí)現(xiàn)有個(gè)問(wèn)題,效率低。但一個(gè) class 往往只有 20% 的函數(shù)會(huì)被經(jīng)常調(diào)用,可能占總調(diào)用次數(shù)的 80% 。每個(gè)消息都需要遍歷一次 objc_method_list 并不合理。如果把經(jīng)常被調(diào)用的函數(shù)緩存下來(lái),那可以大大提高函數(shù)查詢的效率。這也就是 objc_class 中另一個(gè)重要成員 objc_cache 做的事情 - 再找到 foo 之后,把 foo 的 method_name 作為 key ,method_imp 作為 value 給存起來(lái)。當(dāng)再次收到 foo 消息的時(shí)候,可以直接在 cache 里找到,避免去遍歷 objc_method_list.
具體請(qǐng)看大神:
http://tech.glowing.com/cn/objective-c-runtime/