RunTime - 方法交換

上篇我們講到了runtime 的動態(tài)添加屬性和方法,遍歷對象的屬性列表,今天我們來講一下runtime里面更好用的東西 - 方法交換。

在OC里面,一個方法的基礎(chǔ)對象是objc_method
,他的組成結(jié)構(gòu)如下

圖1

一個objc_method 里面包含著 一個SEL(方法名),method_types,和一個method_imp(方法實現(xiàn)的指針),method_imp是一個方法對象里最重要的,它指向該方法實現(xiàn)的地址,所以我們平時看到的方法名,它其實不是一個真正的實現(xiàn)者,可以看作是一個方法唯一的標(biāo)示。

接下來我們要講的方法交換,其實就是交換方法實現(xiàn)的指針。我們來看一下runtime里面相關(guān)的API:

SEL method_getName(Method m)? //獲取方法名

IMP method_getImplementation(Method m)//獲取方法的指針

?int method_getNumberOfArguments(Method m)//獲取方法的參數(shù)個數(shù)

char *method_copyReturnType(Method m)//獲取方法返回值的類型

char *method_copyArgumentType(Method m, unsigned int index)//某個參數(shù)的類型

IMP method_setImplementation(Method m, IMP imp)//設(shè)置方法的指針(替換方法實現(xiàn))

method_exchangeImplementations(Method m1, Method m2)//交換方法的指針(交換方法實現(xiàn))

其中,對指針的操作是方法交換的核心內(nèi)容,用 method_setImplementation 可以進(jìn)行方法的替換,用method_exchangeImplementations就可以完成交換 其用法如下,

例子1:

方法替換

圖2

圖3

在圖二中,我在UIImage的分類里將imageNamed:的IMP替換成自己寫的replaceImage,所以在圖3的實現(xiàn)中,我調(diào)用imageNamed:的時候,程序就跑到了我我新替換的指針方法實現(xiàn)。

例2:

方法交換

圖4

圖4我們用method_exchangeImplementations 將兩個方法的IMP進(jìn)行了互換,當(dāng)我調(diào)用imageNamed:的時候,系統(tǒng)根據(jù)imageNamed
:里現(xiàn)有的IMP(已被替換成imageWithName:)去找到執(zhí)行的地址,當(dāng)我在return 時執(zhí)行[self imageWithName:name]方法的時候,系統(tǒng)也會根據(jù)該方法的IMP去找到相應(yīng)要執(zhí)行的地址。因為imageWithName的IMP已經(jīng)被替換了,所以我執(zhí)行 return [self imageWithName:name]并不會產(chǎn)生死循環(huán)。

說了那么多,方法交換究竟有什么用????

主要用途:批量修改(重定向),數(shù)組臨界值的問題,UIViewController生命周期的調(diào)取

1.批量修改,如上面的例2,該如我需要新增一個換膚系統(tǒng),就可以用imageWithName
替換原生的imageName,這樣在不改變其他代碼的情況下,完成資源的切換。

2.數(shù)組臨界值的問題,突入其來的數(shù)據(jù)越界讓你的措手不及有沒有?解決方法如下

例子3:

在NSarray類別中,新建方法securityObjectAtIndex:,并讓他與NSarray的 方法objectAtIndex:交換指針

//臨界值

圖5

*方法的交換我就講到這里,下篇我們講解如何避免 unrecognized selector sent to instance (找不到對象/方法)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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

  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 1,775評論 0 9
  • 在iOS開發(fā)中,有一種編程方式叫面向切面編程(AOP),這種編程最大好處是,在不修改源代碼的前提下,在原有功能上添...
    vincentgemini閱讀 538評論 0 1
  • 轉(zhuǎn)載:http://yulingtianxia.com/blog/2014/11/05/objective-c-r...
    F麥子閱讀 769評論 0 2
  • 對于從事 iOS 開發(fā)人員來說,所有的人都會答出【runtime 是運(yùn)行時】什么情況下用runtime?大部分人能...
    夢夜繁星閱讀 3,732評論 7 64
  • 本文轉(zhuǎn)載自:http://yulingtianxia.com/blog/2014/11/05/objective-...
    ant_flex閱讀 797評論 0 1