runtime - 方法動態添加

示例:

void actionTest_IMP(id self, SEL _cmd)
{
    NSLog(@"DemoTest");
}

- (void)addMethod
{
    class_addMethod([DemoClass class], @selector(actionTest), (IMP)actionTest_IMP, "v@:");
    // Test
    DemoClass *instance = [[DemoClass alloc] init];
    [instance actionTest];
    [instance release];
}

注意點:使用此actionTest這個方法需要做的處理是在DemoClass這個類的.h文件中要聲明方法,不然編譯過不了。

我們首先定義了一個DemoClass,繼承NSObject,沒有任何自帶方法,接着定義了一個函數。這裏提一句,Objective-C的方法(method)就是一個至少需要兩個參數(self,_cmd)C函數: void actionTest_IMP(id self, SEL _cmd)。接下來在addMethod方法中,我們調用class_addMethod()DemoClass添加方法,class_addMethod()是這樣定義的:

BOOL class_addMethod(Class cls, SEL name, IMP imp, const char *types)

參數說明:

cls:被添加方法的類

name:SEL方法名(Objective-C)

imp:實現這個方法的函數(C)

types:一個定義該函數返回值類型和參數類型的字符串,這個具體會在後面講

接着創建DemoClass的實例,調用actionTest,運行,輸出DemoTest,添加方法成功。

接下來說一下types參數,
比如我們要添加一個這樣的方法:-(int)say:(NSString *)str;
相應的實現函數就應該是這樣:

int say(id self, SEL _cmd, NSString *str) 
{ 
    NSLog(@"%@", str); 
    return 100;//隨便返回個值 
 } 

class_addMethod這句就應該這麼寫:

 class_addMethod([DemoClass class], @selector(say:), (IMP)say, "i@:@");

其中types參數爲”i@:@“,按順序

i 返回值類型int,若是v則表示void

@ 參數id(self)

: SEL(_cmd)

@ id(str)

都是定義好的(Type Encodings),關於Type Encodings的其他類型定義請參考官方文檔

最後調用say:方法:

int a = [instance say:@"something"]; 
NSLog(@"%d", a);

輸出something100

參照前輩經驗並進行了一番測試整理。

發佈了98 篇原創文章 · 獲贊 3 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章