獲取Class的三種方式:
1/ Class clazz_1 = NSStringFromClass(@"ClassName");
2/ Class clazz_2 = [ClassName class];
3/ Class clazz_3 = [ClassInstance class];
可以直接使用clazz_x來創建對應的類對象: [[clazz_1 alloc] init];
獲取協議(protocol)名
Protocol *po = [Protocol NSProtocolFromString:@"protocolName"];
判斷是否實現了某個協議:
[classInstance conformsToProtocol:protocolName];
獲取SEL對象:
1/ SEL sel = [SEL NSSelectorFromString:@"methodName"];
2/ SEL sel = @selector(methodFullName);
判斷某個對象是否可以執行某個方法
[classInstance respondsToSelector:sel];
動態調用方法的兩種方式
1/ [obj performsToSelector:sel];
2/ objc_msgSend(receiver, selector, ...);
2.1/ 需要返回float, 改用objc_msgSend_fpret(receiver, selector, ...);
2.2/ 需要返回結構體, 改用objc_msgSend_stret(receiver, selector, ...);
這個方法需要 #import <objc/message.h>
通過函數指針來調用方法
OC中IMP的定義:
#if !OBJC_OLD_DISPATCH_PROTOTYPES
typedef void (*IMP)(void /* id, SEL, ... */ );
#else
typedef id (*IMP)(id, SEL, ...);
#endif
解釋:
1/ IMP是一個指向方法/函數的實現的指針. 因為OC是完全兼容C的, 第一種定義是對C,第二種是對OC的(因為OC有方法, 方法需要對象來調用)
2/ OBJC_OLD_DISPATCH_PROTOTYPES(分發函數原型). 有啥用呢? 上面說了OC中引入了方法的概念, 而C是沒有的. 方法需要對象調用,而函數不用對象. 所以就需要一個指標來確定IMP指向的是函數還是方法, 這個宏就是來做這件事的. 當將返回的IMP強轉為OC的指向方法的指針, 這個宏保持為1, 當我們將返回的IMP保持默認時, 它為0,意為指向C的函數.
OC中使用IMP調用方法:
TestClass *testClass = [[TestClass alloc] init]; // testWithChar: 是TestClass的一個方法 SEL sel = NSSelectorFromString(@"testWithChar:"); int (*imp)(id, SEL, char) ; // 將返回的IMP指針強轉為OC方法的指針類型 // OC的方法指針類型, 一定要有id(調用者), SEL(調用者要調用的方法名, 參數列表) imp = (int (*)(id, SEL, char))[testClass methodForSelector:sel]; imp(testClass, sel, 'a');