定義
先來看一下method
相關的定義
typedef struct objc_method *Method;
struct objc_method {
SEL method_name;
char *method_types;
IMP method_imp;
}
struct objc_method_list {
struct objc_method_list *obsolete OBJC2_UNAVAILABLE;
int method_count OBJC2_UNAVAILABLE;
#ifdef __LP64__
int space OBJC2_UNAVAILABLE;
#endif
/* variable length structure */
struct objc_method method_list[1] OBJC2_UNAVAILABLE;
}
struct objc_method_description {
SEL name; /**< The name of the method */
char *types; /**< The types of the method arguments */
};
struct objc_method_description_list {
int count;
struct objc_method_description list[1];
};
里邊有三個類型別名,在這兒先解釋一下
- SEL selector 的簡寫,俗稱方法選擇器,實質(zhì)存儲的是方法的名稱
- IMP implement 的簡寫,俗稱方法實現(xiàn),看源碼得知它就是一個函數(shù)指針
- Method 對上述兩者的一個包裝結構.
函數(shù)
method相關的函數(shù)也不是太多,下邊簡單羅列說明一下
//判斷類中是否包含某個方法的實現(xiàn)
BOOL class_respondsToSelector(Class cls, SEL sel)
//獲取類中的方法列表
Method *class_copyMethodList(Class cls, unsigned int *outCount)
//為類添加新的方法,如果方法該方法已存在則返回NO
BOOL class_addMethod(Class cls, SEL name, IMP imp, const char *types)
//替換類中已有方法的實現(xiàn),如果該方法不存在添加該方法
IMP class_replaceMethod(Class cls, SEL name, IMP imp, const char *types)
//獲取類中的某個實例方法(減號方法)
Method class_getInstanceMethod(Class cls, SEL name)
//獲取類中的某個類方法(加號方法)
Method class_getClassMethod(Class cls, SEL name)
//獲取類中的方法實現(xiàn)
IMP class_getMethodImplementation(Class cls, SEL name)
//獲取類中的方法的實現(xiàn),該方法的返回值類型為struct
IMP class_getMethodImplementation_stret(Class cls, SEL name)
//獲取Method中的SEL
SEL method_getName(Method m)
//獲取Method中的IMP
IMP method_getImplementation(Method m)
//獲取方法的Type字符串(包含參數(shù)類型和返回值類型)
const char *method_getTypeEncoding(Method m)
//獲取參數(shù)個數(shù)
unsigned int method_getNumberOfArguments(Method m)
//獲取返回值類型字符串
char *method_copyReturnType(Method m)
//獲取方法中第n個參數(shù)的Type
char *method_copyArgumentType(Method m, unsigned int index)
//獲取Method的描述
struct objc_method_description *method_getDescription(Method m)
//設置Method的IMP
IMP method_setImplementation(Method m, IMP imp)
//替換Method
void method_exchangeImplementations(Method m1, Method m2)
//獲取SEL的名稱
const char *sel_getName(SEL sel)
//注冊一個SEL
SEL sel_registerName(const char *str)
//判斷兩個SEL對象是否相同
BOOL sel_isEqual(SEL lhs, SEL rhs)
//通過塊創(chuàng)建函數(shù)指針,block的形式為^ReturnType(id self,參數(shù),...)
IMP imp_implementationWithBlock(id block)
//獲取IMP中的block
id imp_getBlock(IMP anImp)
//移出IMP中的block
BOOL imp_removeBlock(IMP anImp)
//調(diào)用target對象的sel方法
id objc_msgSend(id target, SEL sel, 參數(shù)列表...)
Showtime
下邊就來玩玩runtime API中的method相關操作
//創(chuàng)建繼承自NSObject類的People類
Class People = objc_allocateClassPair([NSObject class], "People", 0);
//將People類注冊到runtime中
objc_registerClassPair(People);
//注冊test: 方法選擇器
SEL sel = sel_registerName("test:");
//函數(shù)實現(xiàn)
IMP imp = imp_implementationWithBlock(^(id this,id args,...){
NSLog(@"方法的調(diào)用者為 %@",this);
NSLog(@"參數(shù)為 %@",args);
return @"返回值測試";
});
//向People類中添加 test:方法;函數(shù)簽名為@@:@,
// 第一個@表示返回值類型為id,
// 第二個@表示的是函數(shù)的調(diào)用者類型,
// 第三個:表示 SEL
// 第四個@表示需要一個id類型的參數(shù)
class_addMethod(People, sel, imp, "@@:@");
//替換People從NSObject類中繼承而來的description方法
class_replaceMethod(People,@selector(description), imp_implementationWithBlock(^NSString*(id this,...){
return @"我是Person類的對象";}),
"@@:");
//完成 [[People alloc]init];
id p1 = objc_msgSend(objc_msgSend(People, @selector(alloc)),@selector(init));
//調(diào)用p1的sel選擇器的方法,并傳遞@"???"作為參數(shù)
id result = objc_msgSend(p1, sel,@"???");
//輸出sel方法的返回值
NSLog(@"sel 方法的返回值為 : %@",result);
//獲取People類中實現(xiàn)的方法列表
NSLog(@"輸出People類中實現(xiàn)的方法列表");
unsigned int methodCount;
Method * methods = class_copyMethodList(People, &methodCount);
for (int i = 0; i<methodCount; i++) {
NSLog(@"方法名稱:%s",sel_getName(method_getName(methods[i])));
NSLog(@"方法Types:%s",method_getDescription(methods[i])->types);
}
free(methods);
轉(zhuǎn)載自:這里