前言
C語言是靜態(tài)語言,它的工作方式是通過函數(shù)調(diào)用,這樣在編譯時我們就已經(jīng)確定程序如何運行的。而Objective-C是動態(tài)語言,它并非通過調(diào)用類的方法來執(zhí)行功能,而是給對象發(fā)送消息,對象在接收到消息之后會去找匹配的方法來運行。這種做法就把C語言在編譯時的工作挪到了運行時來做,可以獲得額外的靈活性。
簡單理解呢,就是你調(diào)用一個方法,但它最終調(diào)用的實現(xiàn)是可以改變的,而且你可以在運行時給類添加方法。
添加類不存在的方法
下面的代碼定義了兩個按鈕的響應事件,如果直接點擊第一個按鈕,那么程序會奔潰,報錯提示找不到方法,而如果先點擊第二個按鈕,那么再點擊第一個按鈕也不好奔潰了,相反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)就是一個至少需要兩個參數(shù)(self,_cmd)的C函數(shù),這個函數(shù)僅僅輸出一句Hello。接下來在addMethod方法中,我們調(diào) 用class_addMethod()為類添加方法,class_addMethod()是這樣定義的:
BOOL class_addMethod(Class cls, SEL name, IMP imp, const char *types)
參數(shù)說明:
cls:被添加方法的類
name:可以理解為方法名,這個貌似隨便起名,比如我們這里叫sayHello2
imp:實現(xiàn)這個方法的函數(shù)
types:一個定義該函數(shù)返回值類型和參數(shù)類型的字符串
下面舉一個例子來講一下上面的types
int say(id self, SEL _cmd, NSString *str) {
NSLog(@"%@", str);
return 100;//隨便返回個值
}
class_addMethod這句就應該這么寫:
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
稍等