在本文開始之前蚓哩,先發(fā)表下個(gè)人見(jiàn)解上渴。runtime是OC語(yǔ)言的特性喜颁,Method
Swizzling 是蘋果針對(duì)runtime暴露的API接口。如果半开,你使用Method
Swizzling造成了一些的問(wèn)題,那可能是你使用Method Swizzing
的姿勢(shì)有些不太對(duì)奢米。下一篇文章會(huì)對(duì)Method Swizzing 造成的問(wèn)題纠永,
以及為什么會(huì)造成這些問(wèn)題做一個(gè)總結(jié)鬓长。下面先來(lái)說(shuō)說(shuō)本文標(biāo)題的內(nèi)容。
什么是類方法和實(shí)例方法涉波?
1.從標(biāo)識(shí)符角度考慮
在Objective-C中標(biāo)識(shí)符 "-" 是實(shí)例方法,標(biāo)識(shí)符"+"是類方法/靜態(tài)方法啤覆。
2.從調(diào)用方式上考慮
實(shí)例方法的調(diào)用時(shí)需要實(shí)例對(duì)象,而類方法的調(diào)用則可以通過(guò)類直接調(diào)
用相恃。
在runtime中
isa 指針指向
實(shí)例對(duì)象的isa指針指向該實(shí)例對(duì)象的類笨觅,類指向該類元類,元類有點(diǎn)特殊揩魂,統(tǒng)一指向根元類炮温,根元類指向自己火脉。
繼承關(guān)系
類繼承自己的父類柒啤,繼承體系一直往上,最終指向nil方援,元類指向父元類涛癌,最終根元類,指向NSObject拳话。
內(nèi)存分配
指向?qū)嵗瘜?duì)象的指針,存儲(chǔ)在棧區(qū)弃衍;實(shí)例化的Objective-C對(duì)象存儲(chǔ)在堆區(qū),類和元類存在在代碼段岸裙。
實(shí)例方法的調(diào)用
對(duì)象方法的調(diào)用實(shí)際上是發(fā)送消息給這個(gè)對(duì)象速缆,對(duì)象在接受到這個(gè)消息之后。首先激涤,他會(huì)去方法緩存列表中根據(jù)SEL查找函數(shù)指針I(yè)MP判呕,找到之后直接通過(guò)指針調(diào)用該函數(shù)送滞。如果,沒(méi)有找到就去方法列表methodlist中根據(jù)SEL查找函數(shù)指針I(yè)MP边涕。找到后直接通過(guò)指針調(diào)用函數(shù),并且把該方法放在緩存列表中功蜓,如果沒(méi)找到那就沿著繼承體系向上查找宠蚂。如果,還是找不到該方法求厕,那就執(zhí)行消息轉(zhuǎn)發(fā)。
類方法調(diào)用
首先我們知道類方法是保存在該類的元類中的美浦,類在OC中项栏,也可以看成是元類的一個(gè)實(shí)例。當(dāng)類方法被調(diào)用的時(shí)候沼沈,元類首先會(huì)查找本身是否有該類方法的實(shí)現(xiàn),如果沒(méi)有該元類會(huì)向他的父元類繼續(xù)查找該方法康吵,一直找到繼承鏈的頭劈榨。類方法不會(huì)出現(xiàn)向?qū)嵗椒ㄕ也坏降那闆r。因?yàn)榭阶耍绻淮嬖谠擃惙椒ê岛敲丛诰幾g的時(shí)候都通不過(guò)。
關(guān)于實(shí)例方法和類方法的內(nèi)存占用
實(shí)例方法
實(shí)例對(duì)象的創(chuàng)建被分配在堆區(qū)棒妨,該對(duì)象的內(nèi)存管理完全交給了ARC去完成含长。實(shí)例方法只有在調(diào)用的時(shí)候才會(huì)分配內(nèi)存伏穆,這個(gè)點(diǎn)可以通過(guò)Xcode自帶的Instruments工具中Allocations來(lái)做測(cè)試,證明想法陪腌,樓主這里就不做演示烟瞧。
類方法
類方法的調(diào)用不同于實(shí)例方法,下面來(lái)看一張圖:
一個(gè)類可以有n個(gè)實(shí)例化對(duì)象参滴,但是一個(gè)元類只有一個(gè)類實(shí)例,這個(gè)類的isa唯一指向元類请唱。當(dāng)App在啟動(dòng)的時(shí)候就已經(jīng)為類方法分配了內(nèi)存过蹂,而且貫穿整個(gè)app應(yīng)用的生命周期。類方法的調(diào)用會(huì)常駐內(nèi)存酷勺,不是被調(diào)用才會(huì)常駐內(nèi)存,而是一直都會(huì)甚亭。