iOS class_addMethod使用

前言


近期項目不急,有時間看一些自己想看的東西。記得面試的時候都是在問runtimer的知識點,自己雖然知道一點這里面的知識點,但是很零碎。所以在這幾天好好的研究一下。其實我也問過一個做sdk的朋友,他也說基本上平時開發用的不是很多。做sdk的用的比較多,因為要獲取開發人員的某些屬性,或者在不知道開發人員的類的結構下添加方法等。本次說class_addMethod 這個很有用的方法,感覺他就是一個作弊器。

正文


/**

* Adds a new method to a class with a given name and implementation.

*

* @param cls The class to which to add a method.

* @param name A selector that specifies the name of the method being added.

* @param imp A function which is the implementation of the new method. The function must take at least two arguments—self and _cmd.

* @param types An array of characters that describe the types of the arguments to the method.

*

* @return YES if the method was added successfully, otherwise NO

*? (for example, the class already contains a method implementation with that name).

*

* @note class_addMethod will add an override of a superclass's implementation,

*? but will not replace an existing implementation in this class.

*? To change an existing implementation, use method_setImplementation.

*/

OBJC_EXPORT BOOL class_addMethod(Class cls, SEL name, IMP imp,

const char *types)

__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);

這個是API文檔的解釋,基本就是說這可以加入新的方法到一個類里面,然后介紹這里面幾個參數的作用之類的。我感覺無論什么都要自己親身實踐才行,所以直接先上代碼:

- (void)viewDidLoad {

[super viewDidLoad];

//動態添加一個方法

Person *p = [[Person alloc]init];

class_addMethod([Person class], @selector(printPerson), class_getMethodImplementation([ViewController class], @selector(find)), "v@:");

[p performSelector:@selector(printPerson)];

}

非常簡單的代碼片段,我有一個Person類,現在我要在運行的時候給他增加一個方法,并且調用這個方法。

class_addMethod(Class cls, SEL name, IMP imp,

const char *types)

首先我們看看這個方法里面的參數:

Class cos:我們需要一個class,比如我的[Person class]。

SEL name:這個很有意思,這個名字自己可以隨意想,就是添加的方法在本類里面叫做的名字,但是方法的格式一定要和你需要添加的方法的格式一樣,比如有無參數。(有幾個小伙伴問我Demo里面的findInSelf這個方法沒有找到,請看這里呀。這個就是里面為啥沒有findInSelf方法而可以直接調用的原因)

IMP imp:IMP就是Implementation的縮寫,它是指向一個方法實現的指針,每一個方法都有一個對應的IMP。這里需要的是IMP,所以你不能直接寫方法,需要用到一個方法:

OBJC_EXPORT IMP class_getMethodImplementation(Class cls, SEL name)

__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);

這個方法也是runtime的方法,就是獲得對應的方法的指針,也就是IMP。

const char *types:這一個也很有意思,我剛開始也很費解,結果看了好多人的解釋我釋然了,知道嗎,我釋然啦,????。這個東西其實也很好理解:

比如:”v@:”意思就是這已是一個void類型的方法,沒有參數傳入。

再比如 “i@:”就是說這是一個int類型的方法,沒有參數傳入。

再再比如”i@:@”就是說這是一個int類型的方法,又一個參數傳入。

好了,參數解釋完了,還有一點需要注意,用這個方法添加的方法是無法直接調用的,必須用performSelector:調用。為甚么呢???

因為performSelector是運行時系統負責去找方法的,在編譯時候不做任何校驗;如果直接調用編譯是會自動校驗。

知道為甚么了吧,你添加方法是在運行時添加的,你在編譯的時候還沒有這個本類方法,所以當然不行啦。

結束

啦啦啦,結束啦,代碼示例在此,如果您覺得還可以,給個??吧。

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

推薦閱讀更多精彩內容

  • 轉至元數據結尾創建: 董瀟偉,最新修改于: 十二月 23, 2016 轉至元數據起始第一章:isa和Class一....
    40c0490e5268閱讀 1,788評論 0 9
  • 我們常常會聽說 Objective-C 是一門動態語言,那么這個「動態」表現在哪呢?我想最主要的表現就是 Obje...
    Ethan_Struggle閱讀 2,232評論 0 7
  • Method Swizzling參考資料 1.用到的運行時基礎知識介紹 SEL : 方法選擇器,SEL是函數ob...
    shannoon閱讀 1,399評論 0 7
  • Objective-C語言是一門動態語言,它將很多靜態語言在編譯和鏈接時期做的事放到了運行時來處理。這種動態語言的...
    有一種再見叫青春閱讀 612評論 0 3
  • 這幾天一直在寫數學作業,不過三天,刷刷的往后翻,頁數實在讓人驚喜,心情也很興奮。 這在以前是件很不可思議的事情—...
    忽爾今至閱讀 309評論 0 0