消息發(fā)送
objc_msgSend流程

未命名 (2).jpg
動態(tài)方法解析流程

未命名 (1).jpg
- (void)test1{}
+ (void)test2{}
void c_test(id self, SEL _cmd){}
// - 對象方法的動態(tài)解析
+ (BOOL)resolveClassMethod:(SEL)sel{
if (sel == @selector(test)) {
// - 添加test方法, 并將test的方法實(shí)現(xiàn)改為test2的方法實(shí)現(xiàn)
Method method = class_getInstanceMethod(self, @selector(test1));
class_addMethod(self, sel, method_getImplementation(method), method_getTypeEncoding(method));
return YES;
// - 2. 添加C語言函數(shù), 并將test的方法實(shí)現(xiàn)改為c_test的函數(shù)實(shí)現(xiàn)
class_addMethod(self, sel, (IMP)c_test, "v16@0:8");
}
return [super resolveClassMethod:sel];
}
// - 實(shí)例方法的動態(tài)解析
+ (BOOL)resolveInstanceMethod:(SEL)sel{
// - 1. 添加test方法, 并將test的方法實(shí)現(xiàn)改為test2的方法實(shí)現(xiàn)
if (sel == @selector(test)) {
Method method = class_getClassMethod(object_getClass(self), @selector(test2));
class_addMethod(object_getClass(self), sel, method_getImplementation(method), method_getTypeEncoding(method));
return YES;
// - 2. 添加C語言函數(shù), 并將test的方法實(shí)現(xiàn)改為c_test的函數(shù)實(shí)現(xiàn)
class_addMethod(self, sel, (IMP)c_test, "v16@0:8");
}
return [super resolveInstanceMethod:sel];
}
消息轉(zhuǎn)發(fā)流程

未命名.jpg
-(void)test{}
-(void)test1{}
+(void)test2{}
+(int)test:(int)age height:(float)height{ }
// - 快轉(zhuǎn)發(fā), 讓cat去調(diào)用test方法
- (id)forwardingTargetForSelector:(SEL)aSelector{
if (aSelector == @selector(test)) {
// - 實(shí)例方法
return [Cat new];
// - 類方法
return [Cat class]
}
return [super forwardingTargetForSelector:aSelector];
}
// - 慢轉(zhuǎn)發(fā), 讓cat去調(diào)用test方法
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector{
if (aSelector == @selector(test)) {
// - 沒有參數(shù)的簽名
return [NSMethodSignature signatureWithObjCTypes:"v16@0:8"];
}
if (aSelector == @selector(test:height:)) {
// - 有參數(shù)的簽名
return [NSMethodSignature signatureWithObjCTypes:"i24@0:8i16f20"];
}
return [super methodSignatureForSelector:aSelector];
}
- (void)forwardInvocation:(NSInvocation *)anInvocation{
// - 讓cat去調(diào)用方法
[anInvocation invokeWithTarget:[Cat new]];
// - 讓cat去調(diào)用另一個(gè)方法
anInvocation.target = [Cat new];
anInvocation.selector = @selector(test1);
[anInvocation invoke];
// - 類方法
anInvocation.target = [Cat class];
anInvocation.selector = @selector(test1);
[anInvocation invoke];
// - 帶參數(shù)的方法
anInvocation.target = [Cat new];
anInvocation.selector = @selector(test1);
int age = 0;
int hei = 0;
[anInvocation getArgument:&age atIndex:2];
[anInvocation getArgument:&hei atIndex:3];
[anInvocation setArgument:&age atIndex:2];
[anInvocation setArgument:&hei atIndex:3];
[anInvocation invoke];
int result = 0;
[anInvocation getReturnValue:&result];
}