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