前言
C語言是靜態(tài)語言,它的工作方式是通過函數(shù)調(diào)用,這樣在編譯時(shí)我們就已經(jīng)確定程序如何運(yùn)行的辜伟。而Objective-C是動(dòng)態(tài)語言,它并非通過調(diào)用類的方法來執(zhí)行功能悬垃,而是給對象發(fā)送消息游昼,對象在接收到消息之后會(huì)去找匹配的方法來運(yùn)行。這種做法就把C語言在編譯時(shí)的工作挪到了運(yùn)行時(shí)來做尝蠕,可以獲得額外的靈活性烘豌。
簡單理解呢,就是你調(diào)用一個(gè)方法看彼,但它最終調(diào)用的實(shí)現(xiàn)是可以改變的,而且你可以在運(yùn)行時(shí)給類添加方法廊佩。
添加類不存在的方法
下面的代碼定義了兩個(gè)按鈕的響應(yīng)事件囚聚,如果直接點(diǎn)擊第一個(gè)按鈕,那么程序會(huì)奔潰标锄,報(bào)錯(cuò)提示找不到方法顽铸,而如果先點(diǎn)擊第二個(gè)按鈕,那么再點(diǎn)擊第一個(gè)按鈕也不好奔潰了料皇,相反sayHello函數(shù)得到了調(diào)用谓松。
void sayHello(id self, SEL _cmd)
{
NSLog(@"hello !");
}
- (IBAction)btnClicked:(id)sender {
[self performSelector:@selector(sayHello2)];
}
- (IBAction)swizzlingBtnClicked:(id)sender {
class_addMethod([self class], @selector(sayHello2), (IMP)sayHello, "v@:");
}
這里提一句,Obj-C的方法 (method)就是一個(gè)至少需要兩個(gè)參數(shù)(self践剂,_cmd)的C函數(shù)鬼譬,這個(gè)函數(shù)僅僅輸出一句Hello。接下來在addMethod方法中逊脯,我們調(diào) 用class_addMethod()為類添加方法优质,class_addMethod()是這樣定義的:
BOOL class_addMethod(Class cls, SEL name, IMP imp, const char *types)
參數(shù)說明:
cls:被添加方法的類
name:可以理解為方法名,這個(gè)貌似隨便起名军洼,比如我們這里叫sayHello2
imp:實(shí)現(xiàn)這個(gè)方法的函數(shù)
types:一個(gè)定義該函數(shù)返回值類型和參數(shù)類型的字符串
下面舉一個(gè)例子來講一下上面的types
int say(id self, SEL _cmd, NSString *str) {
NSLog(@"%@", str);
return 100;//隨便返回個(gè)值
}
class_addMethod這句就應(yīng)該這么寫:
1
class_addMethod([EmptyClass class], @selector(say:), (IMP)say, "i@:@");
其中types參數(shù)為"i@:@“巩螃,按順序分別表示:
i:返回值類型int,若是v則表示void
@:參數(shù)id(self)
::SEL(_cmd)
@:id(str)
demo
稍等