一,SEl和IMP到底是什么
SEL : 類成員方法的指針,但不同于C語言中的函數(shù)指針关摇,函數(shù)指針直接保存了方法的地址荒叶,但SEL只是方法編號(hào)。IMP:一個(gè)函數(shù)指針,保存了方法的地址
IMP和SEL關(guān)系
每一個(gè)繼承于NSObject的類都能自動(dòng)獲得runtime的支持输虱。在這樣的一個(gè)類中些楣,有一個(gè)isa指針,指向該類定義的數(shù)據(jù)結(jié)構(gòu)體,這個(gè)結(jié)構(gòu)體是由編譯器編譯時(shí)為類(需繼承于NSObject)創(chuàng)建的.在這個(gè)結(jié)構(gòu)體中有包括了指向其父類類定義的指針以及 Dispatch table. Dispatch table是一張SEL和IMP的對(duì)應(yīng)表宪睹。也就是說方法編號(hào)SEL最后還是要通過Dispatch table表尋找到對(duì)應(yīng)的IMP愁茁,IMP就是一個(gè)函數(shù)指針,然后執(zhí)行這個(gè)方法
1)通過方法獲得方法的編號(hào):SEL methodId=@selector(methodName);或者SEL methodId = NSSelectorFromString(methodName);
2)通過方法編號(hào)執(zhí)行該編號(hào)的方法: [self performSelector:methodId withObject:nil];
3)通過方法編號(hào)獲取該編號(hào)的方法名 NSString*methodName = NSStringFromSelector(methodId);
4)通過方法編號(hào)獲得IMP IMP methodPoint = [self methodForSelector:methodId];
5)執(zhí)行IMP void (*func)(id, SEL, id) = (void *)imp; func(self, methodName,param);
注意分析:如果方法沒有傳入?yún)?shù)時(shí):void (*func)(id, SEL) = (void *)imp; func(self, methodName);
如果方法傳入一個(gè)參數(shù)時(shí):void (*func)(id, SEL,id) = (void *)imp; func(self, methodName,param);
如果方法傳入倆個(gè)參數(shù)時(shí):void (*func)(id, SEL,id,id) = (void *)imp; func(self, methodName,param1,param2);
參考以下文獻(xiàn):
文獻(xiàn)