前言
近期項(xiàng)目不急,有時(shí)間看一些自己想看的東西刹淌。記得面試的時(shí)候都是在問(wèn)runtimer的知識(shí)點(diǎn)饶氏,自己雖然知道一點(diǎn)這里面的知識(shí)點(diǎn),但是很零碎有勾。所以在這幾天好好的研究一下疹启。其實(shí)我也問(wèn)過(guò)一個(gè)做sdk的朋友,他也說(shuō)基本上平時(shí)開(kāi)發(fā)用的不是很多蔼卡。做sdk的用的比較多喊崖,因?yàn)橐@取開(kāi)發(fā)人員的某些屬性,或者在不知道開(kāi)發(fā)人員的類的結(jié)構(gòu)下添加方法等雇逞。本次說(shuō)class_addMethod 這個(gè)很有用的方法荤懂,感覺(jué)他就是一個(gè)作弊器。
正文
/**
* 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);
這個(gè)是API文檔的解釋塘砸,基本就是說(shuō)這可以加入新的方法到一個(gè)類里面节仿,然后介紹這里面幾個(gè)參數(shù)的作用之類的。我感覺(jué)無(wú)論什么都要自己親身實(shí)踐才行掉蔬,所以直接先上代碼:
- (void)viewDidLoad {
[super viewDidLoad];
//動(dòng)態(tài)添加一個(gè)方法
Person *p = [[Person alloc]init];
class_addMethod([Person class], @selector(printPerson), class_getMethodImplementation([ViewController class], @selector(find)), "v@:");
[p performSelector:@selector(printPerson)];
}
非常簡(jiǎn)單的代碼片段廊宪,我有一個(gè)Person類,現(xiàn)在我要在運(yùn)行的時(shí)候給他增加一個(gè)方法女轿,并且調(diào)用這個(gè)方法箭启。
class_addMethod(Class cls, SEL name, IMP imp,
const char *types)
首先我們看看這個(gè)方法里面的參數(shù):
Class cos:我們需要一個(gè)class,比如我的[Person class]蛉迹。
SEL name:這個(gè)很有意思傅寡,這個(gè)名字自己可以隨意想,就是添加的方法在本類里面叫做的名字北救,但是方法的格式一定要和你需要添加的方法的格式一樣荐操,比如有無(wú)參數(shù)。
IMP imp:IMP就是Implementation的縮寫(xiě)珍策,它是指向一個(gè)方法實(shí)現(xiàn)的指針托启,每一個(gè)方法都有一個(gè)對(duì)應(yīng)的IMP。這里需要的是IMP膛壹,所以你不能直接寫(xiě)方法驾中,需要用到一個(gè)方法:
OBJC_EXPORT IMP class_getMethodImplementation(Class cls, SEL name)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
這個(gè)方法也是runtime的方法唉堪,就是獲得對(duì)應(yīng)的方法的指針,也就是IMP肩民。
const char *types:這一個(gè)也很有意思唠亚,我剛開(kāi)始也很費(fèi)解,結(jié)果看了好多人的解釋我釋然了持痰,知道嗎灶搜,我釋然啦,????工窍。這個(gè)東西其實(shí)也很好理解:
比如:”v@:”意思就是這已是一個(gè)void類型的方法割卖,沒(méi)有參數(shù)傳入。
再比如 “i@:”就是說(shuō)這是一個(gè)int類型的方法患雏,沒(méi)有參數(shù)傳入鹏溯。
再再比如”i@:@”就是說(shuō)這是一個(gè)int類型的方法,又一個(gè)參數(shù)傳入淹仑。
好了丙挽,參數(shù)解釋完了,還有一點(diǎn)需要注意匀借,用這個(gè)方法添加的方法是無(wú)法直接調(diào)用的颜阐,必須用performSelector:調(diào)用。為甚么呢吓肋?凳怨??
因?yàn)閜erformSelector是運(yùn)行時(shí)系統(tǒng)負(fù)責(zé)去找方法的是鬼,在編譯時(shí)候不做任何校驗(yàn)肤舞;如果直接調(diào)用編譯是會(huì)自動(dòng)校驗(yàn)。
知道為甚么了吧屑咳,你添加方法是在運(yùn)行時(shí)添加的萨赁,你在編譯的時(shí)候還沒(méi)有這個(gè)本類方法弊琴,所以當(dāng)然不行啦兆龙。
結(jié)束
啦啦啦,結(jié)束啦敲董,代碼示例在此,如果您覺(jué)得還可以紫皇,給個(gè)??吧。
轉(zhuǎn)自:http://blog.csdn.net/github_30943901/article/details/51210346