OC語言是C語言
的超集贝室,C語言
有個特點就是在編譯期間就已經(jīng)確定了對應的被調(diào)用的方法沾鳄,行業(yè)術語是以靜態(tài)綁定的方式進行地址定位诸蚕,而調(diào)用方法以硬編碼的形式存儲
舀射,某種程度上也側(cè)面說明其運行效率高。而OC語言的方法
調(diào)用采用向?qū)ο蟀l(fā)送消息的形式進行驹碍,所以對于方法的調(diào)用并不能在編譯期間確定方法的所處內(nèi)存地址
壁涎。
給對象發(fā)送消息是通過objc_msgSend(_cmd, sel, ...)
方法進行的凡恍,所以每個對象接收者都會存一張方法表,如果該表中含有存儲的方法怔球,此時會直接跳到方法實現(xiàn)中執(zhí)行相應的方法體嚼酝。假如每次都查找類中所存儲的方法表,那么勢必會影響方法執(zhí)行的效率竟坛。為此闽巩,OC在每個類中都添加了一個方法緩存表(fast map),這樣就能將第一次查找的方法存儲在緩存表里担汤,下次需要用的時候直接從緩存表里直接拿到方法體涎跨,以保證正常的方法調(diào)用效率
。
在理解消息轉(zhuǎn)發(fā)之前崭歧,先了解一下OC中的對象
在OC中對象分為三類隅很,分別是實例對象、類對象以及元類對象
率碾,這三類對象之間是有聯(lián)系的外构。從isa指針指向來說的話,實例對象的isa指針指向類對象播掷,類對象的isa指針指向元類對象,元類對象的isa指針指向基類元類對象撼班。因為OC中類實質(zhì)是一個結(jié)構體歧匈,除了isa指針,還包含superclass指針(實質(zhì)都是NSObject的對象)砰嘁,還包含屬性方法表等件炉。類是對數(shù)據(jù)以及方法的封裝,所以這三者的關系鏈也就由isa指針鏈接起來了矮湘。
isa指針的實際應用
不如說一個場景斟冕,如果調(diào)用類Class_a
中的方法method_a
,此時系統(tǒng)會通過實例對象中的isa指針找到類對象缅阳,然后通過查找在類對象中存儲的方法表磕蛇,找到要執(zhí)行的方法。同理十办,如果要調(diào)用類Class_a
中的類方法class_method_a
秀撇,此時系統(tǒng)會通過類對象中的isa
指針找到當前類的元類對象,然后通過元類對象中的方法表找到對應的類方法向族,進而調(diào)用呵燕。
所以類對象存儲了實例對象的相關的屬性方法信息,元類對象存儲了類對象的相關的屬性方法信息
件相。調(diào)用鏈也是沿著類信息存儲方向進行調(diào)用的再扭。
superclass 指針的作用
類中存儲的superclass
是用來指向繼承關系的父類對象的氧苍,依舊說場景。
- 如果想要調(diào)用Student實例對象的基類Person對象方法泛范,調(diào)用過程是什么樣的呢让虐?
首先會通過Student實例對象的
isa指針
找到Student的類對象,通過查找類對象方法表存儲的方法敦跌,在沒有找到的情況下澄干,通過Superclass指針找到Student的繼承的類對象Person進行方法索引,找到調(diào)用其方法柠傍。
- 如果想要調(diào)用Student實例對象的
NSObject
對象方法麸俘,過程如何?
首先會通過Student的實例對象的
isa指針
找到Student的類對象惧笛,通過查找Student的類對象Person存儲的方法表从媚,不存在的話,再通過Person類對象中的isa指針
找到Person的元類對象患整,最后查找存儲在元類對象的屬性方法表找到要調(diào)用的的方法拜效,最后調(diào)用。
匯總
以下圖為例說明
- isa指向問題
- 實例對象Instance 的
isa
指向類對象Class- 類對象Class的
isa指針
指向元類對象meta-class- 基類的元類對象meta-class的
isa
指向自己
- superclass指向問題
- 類對象class的
superclass指針
指向父類的class類
對象各谚,如果沒有父類紧憾,superclass
指針為nil
- 元類對象
meta-class
的superclass
指向父類的元類對象meta-class
,基類的元類對象meta-class
的superclass
指向基類的類對象class
(注意是基類的對象class)
- 實例
對象instance
調(diào)用對象方法的過程鏈
- 通過實例對象instance的
isa指針
找到類對象class昌渤,找到即調(diào)用- 如果找不到赴穗,通過實例對象的
instance
中的superclass找到父類對象,通過父類對象的isa指針
找到父類對象的類對象class
膀息,找到調(diào)用方法- 如果仍然找不到般眉,那么系統(tǒng)會通過消息轉(zhuǎn)發(fā)機制進行消息轉(zhuǎn)發(fā),走消息轉(zhuǎn)發(fā)的響應鏈潜支,最后如果都沒有能夠處理消息的方法的話甸赃,那么會拋出
unselector
的異常
- 類對象調(diào)用類方法的過程鏈
- 通過類對象
class isa
指針找到元類對象meta-class,通過存儲在元類對象的方法表查找對應的方法進行調(diào)用- 如果沒有找到冗酿,那么通過
class
的superclass
指針找到父類superclass
埠对,然后通過父類的superclass
的isa
指針找到父類的元類對象super-meta-class
,通過存儲在父類的元類對象meta-class
找到類對象進行調(diào)用已烤。
- 關于
class
對象鸠窗、meta-class
對象的本質(zhì)
class對象、meta-class對象
的本質(zhì)是結(jié)構體 struct objc_class
.