iOS runtime如何交換兩個(gè)類方法

如有轉(zhuǎn)載,請(qǐng)標(biāo)明出處:iOS runtime如何交換兩個(gè)類方法

runtime交換實(shí)例方法隧饼,老生常談的問題,很多blog都有介紹過诞丽,但是好像暫時(shí)沒有找到過如何交換兩個(gè)類的類方法。通過對(duì)元類的學(xué)習(xí)刑赶,作者自行摸索懂衩,終于嘗試出如何交換兩個(gè)類方法。元類的具體內(nèi)容谒所,見《類對(duì)象沛申、元類》一章。

實(shí)例方法的交換:
void class_swizzleInstanceMethod(Class class, SEL originalSEL, SEL replacementSEL)
{
    //class_getInstanceMethod()尖淘,如果子類沒有實(shí)現(xiàn)相應(yīng)的方法,則會(huì)返回父類的方法村生。
    Method originMethod = class_getInstanceMethod(class, originalSEL);
    Method replaceMethod = class_getInstanceMethod(class, replacementSEL);
    
    //class_addMethod() 判斷originalSEL是否在子類中實(shí)現(xiàn)饼丘,如果只是繼承了父類的方法,沒有重寫肄鸽,那么直接調(diào)用method_exchangeImplementations,則會(huì)交換父類中的方法和當(dāng)前的實(shí)現(xiàn)方法典徘。此時(shí)如果用父類調(diào)用originalSEL,因?yàn)榉椒ㄒ呀?jīng)與子類中調(diào)換帜平,所以父類中找不到相應(yīng)的實(shí)現(xiàn)梅鹦,會(huì)拋出異常unrecognized selector.
    //當(dāng)class_addMethod() 返回YES時(shí),說明子類未實(shí)現(xiàn)此方法(根據(jù)SEL判斷)齐唆,此時(shí)class_addMethod會(huì)添加(名字為originalSEL,實(shí)現(xiàn)為replaceMethod)的方法蝶念。此時(shí)在將replacementSEL的實(shí)現(xiàn)替換為originMethod的實(shí)現(xiàn)即可芋绸。
    //當(dāng)class_addMethod() 返回NO時(shí)担敌,說明子類中有該實(shí)現(xiàn)方法,此時(shí)直接調(diào)用method_exchangeImplementations交換兩個(gè)方法的實(shí)現(xiàn)即可全封。
    //注:如果在子類中實(shí)現(xiàn)此方法了马昙,即使只是單純的調(diào)用super刹悴,一樣算重寫了父類的方法,所以class_addMethod() 會(huì)返回NO子房。
    
    //可用BaseClass實(shí)驗(yàn)
    if(class_addMethod(class, originalSEL, method_getImplementation(replaceMethod),method_getTypeEncoding(replaceMethod)))
    {
        class_replaceMethod(class,replacementSEL, method_getImplementation(originMethod), method_getTypeEncoding(originMethod));
    }else {
        method_exchangeImplementations(originMethod, replaceMethod);
    }
}

通過如上代碼就轧,傳入相應(yīng)的Class及selector,即可交換對(duì)應(yīng)的方法妒御。

類方法的交換:

通過對(duì)元類的學(xué)習(xí),我們可以知道乎莉,其實(shí)Class(也就是類)本身也是一個(gè)對(duì)象,他的類可以通過object_getClass(class)方法得到哼鬓,這種類對(duì)象的類就叫做元類。所以一個(gè)類的類方法魄宏,也就是其元類的實(shí)例方法存筏,我們可以通過將其元類傳入味榛,即可交互類方法椭坚。

void class_swizzleClassMethod(Class class, SEL originalSEL, SEL replacementSEL)
{
    //類方法實(shí)際上是儲(chǔ)存在類對(duì)象的類(即元類)中搏色,即類方法相當(dāng)于元類的實(shí)例方法,所以只需要把元類傳入,其他邏輯和交互實(shí)例方法一樣垂涯。
    Class class2 = object_getClass(class);
    class_swizzleInstanceMethod(class2, originalSEL, replacementSEL);
}

雖然代碼很容易,但是里面的原理并不是很簡(jiǎn)單耕赘。

附上demo

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市九火,隨后出現(xiàn)的幾起案子册招,更是在濱河造成了極大的恐慌,老刑警劉巖是掰,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異震叙,居然都是意外死亡散休,警方通過查閱死者的電腦和手機(jī)媒楼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門划址,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人夺颤,你說我怎么就攤上這事胁勺∈览剑” “怎么了?”我有些...
    開封第一講書人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵寥裂,是天一觀的道長(zhǎng)案疲。 經(jīng)常有香客問我,道長(zhǎng)褐啡,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任低飒,我火速辦了婚禮,結(jié)果婚禮上褥赊,老公的妹妹穿的比我還像新娘。我一直安慰自己崭倘,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開白布琅坡。 她就那樣靜靜地躺著残家,像睡著了一般。 火紅的嫁衣襯著肌膚如雪坞淮。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,166評(píng)論 1 284
  • 那天诺擅,我揣著相機(jī)與錄音啡直,去河邊找鬼烁涌。 笑死酒觅,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的舷丹。 我是一名探鬼主播,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼谋币,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼装获!你這毒婦竟也來了厉颤?” 一聲冷哼從身側(cè)響起穴豫,我...
    開封第一講書人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤精肃,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后司抱,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡匀谣,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年资溃,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片溶锭。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖垫毙,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情综芥,我是刑警寧澤猎拨,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站迟几,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏类腮。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一缸逃、第九天 我趴在偏房一處隱蔽的房頂上張望厂抽。 院中可真熱鬧需频,春花似錦筷凤、人聲如沸苞七。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)乾蓬。三九已至,卻和暖如春任内,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背死嗦。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留棚品,地道東北人廊敌。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像骡澈,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子肋殴,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

推薦閱讀更多精彩內(nèi)容