美文网首页
Runtime 之 OC中的方法调用objc_msgSend

Runtime 之 OC中的方法调用objc_msgSend

作者: 有梦想的狼 | 来源:发表于2020-03-05 10:22 被阅读0次

    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];
      }
      
    1.3. 消息转发: 消息转发
    - (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]];
    }
    
    
    

    相关文章

      网友评论

          本文标题:Runtime 之 OC中的方法调用objc_msgSend

          本文链接:https://www.haomeiwen.com/subject/bhstrhtx.html