OC中的方法调用,其实都是转换为objc_msgSend函数的调用
-
objc_msgSend的执行流程可以分为3大阶段
1.1. 消息发送: 消息发送
1.2. 动态方法解析: 动态方法解析
动态添加方法:
//other方法 void other(id self, SEL _cmd) { NSLog(@"%@-%s-%s", self, sel_getName(_cmd), _cmd); } //动态添加对象方法 + (BOOL)resolveInstanceMethod:(SEL)sel{ if (sel == @selector(test)) { Method method = class_getInstanceMethod(self, @selector(other)) class_addMethod(self, sel, method_getImplementation(method), method_getTypeEncoding(method)) return YES; } return [super resolveInstanceMethod:sel]; } //动态添加类方法 + (BOOL)resolveClassMethod:(SEL)sel{ if (sel == @selector(test)) { Method method = class_getInstanceMethod(self, @selector(other)) class_addMethod(self, sel, method_getImplementation(method), method_getTypeEncoding(method)) return YES; } return [super resolveClassMethod:sel]; }
- (id)forwardingTargetForSelector:(SEL)aSelector
{
if (aSelector == @selector(test)) {
// objc_msgSend([[MJCat alloc] init], aSelector)
return [[MJCat alloc] init];
}
return [super forwardingTargetForSelector:aSelector];
}
// 方法签名:返回值类型、参数类型
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
{
if (aSelector == @selector(test)) {
//return [NSMethodSignature signatureWithObjCTypes:"v16@0:8"];
return [NSMethodSignature signatureWithObjCTypes:"v@:"];
}
return [super methodSignatureForSelector:aSelector];
}
// NSInvocation封装了一个方法调用,包括:方法调用者、方法名、方法参数
// anInvocation.target 方法调用者
// anInvocation.selector 方法名
// [anInvocation getArgument:NULL atIndex:0]
- (void)forwardInvocation:(NSInvocation *)anInvocation
{
// anInvocation.target = [[MJCat alloc] init];
// [anInvocation invoke];
[anInvocation invokeWithTarget:[[MJCat alloc] init]];
}
网友评论