美文网首页
01--方法本质03--面试题分析

01--方法本质03--面试题分析

作者: 修_远 | 来源:发表于2020-06-15 16:51 被阅读0次

    对方法的探索,全篇分六个章节

    01-方法本质-方法初探

    02-方法本质-objc_msgSend的使用

    03-方法本质-面试题分析

    04-方法本质-lookUpImpOrForward 介绍

    05-方法本质-消息查找流程

    06-方法本质-消息转发流程

    三、面试题分析

    前言

    本章节分析下面两类方法的区别

    self.class 和 super.class

    isKindOfClass 和 isMemberOfClass

    [toc]

    3.1 self.class 和 super.class

    • 测试代码

      - (instancetype)init {
          if (self = [super init]) {
              NSLog(@"self.class  : %@",self.class);
              NSLog(@"super.class : %@",super.class);
          }
          return self;
      }
      
    • 输出

      self.class  : SRStudent
      super.class : SRStudent
      
    • 分析

      1. class 方法有两个隐藏参数,一个 self,一个是 SEL
      2. super.class 调用的方法是 objc_msgSendSuper,消息接受者还是 self
      3. super.class 只是表示在方法查找的时候跳过从自己的方法列表中查找,直接从父类方法列表中开始查找;

    3.2 isKindOfClass 和 isMemberOfClass

    • 方法源码

      + (BOOL)isMemberOfClass:(Class)cls {
          return object_getClass((id)self) == cls;
      }
      
      - (BOOL)isMemberOfClass:(Class)cls {
          return [self class] == cls;
      }
      
      + (BOOL)isKindOfClass:(Class)cls {
          for (Class tcls = object_getClass((id)self); tcls; tcls = tcls->superclass) {
              if (tcls == cls) return YES;
          }
          return NO;
      }
      
      - (BOOL)isKindOfClass:(Class)cls {
          for (Class tcls = [self class]; tcls; tcls = tcls->superclass) {
              if (tcls == cls) return YES;
          }
          return NO;
      }
      
    • isKindOfClass总结

      1.先取比较对象的 cls
      * 如果是实例对象,则取的是 class,实例对象->类对象
      * 如果是类对象,则取的是元类,类对象->元类

      2.然后 遍历 clssuperclass
      * 如果匹配到相同的,直接返回 YES
      * 如果一直没匹配到相同,返回 NO

    • isMemberOfClass总结

      • 选取比较对象的 cls,直接跟被比较的对象比较
      • 相对于 isKindOfClass,不会去遍历 superclass 进行匹配。
      • 如果是实例对象,则取的是 class,实例对象->类对象,用类对象比较
      • 如果是类对象,则取的是元类,类对象->元类,用元类对象比较

    3.2.1 类方法调用例子

    1. + (BOOL)isKindOfClass:(Class)cls 方法分析

      • 方法调用格式
        [A isKindOfClass:B]

        • A-tcls 初始值:A的元类
        • A-tcls 偏移值:A的元类的父类
        • B-cls:用来做比较的类

        A的元类/A的元类的父类/包括NSObject类 只要有 和B相同的即为真

      • 方法调用例子

        1. BOOL re1 = [(id)[NSObject class] isKindOfClass:[NSObject class]]; // 1
            * A : NSObject元类/NSObject类
            * B : NSObject类
        A和B有一个相同的NSObject类,所以返回真
        
        2. BOOL re3 = [(id)[LGPerson class] isKindOfClass:[LGPerson class]];       // 0
    
    
            * A : LGPerson元类/NSObject元类/NSObject类
            * B : LGPerson类
        A和B没有一个相同的类,所以返回假
    
    1. + (BOOL)isMemberOfClass:(Class)cls 方法分析

      • 方法调用格式
        [A isMemberOfClass:B]

        • A-self:A的元类
        • B-cls:用来做比较的类
      • 方法调用例子

        1. BOOL re2 = [(id)[NSObject class] isMemberOfClass:[NSObject class]]; // 0
            * A : NSObject元类
            * B : NSObject类
            不相同,所以返回假
        2. BOOL re4 = [(id)[LGPerson class] isMemberOfClass:[LGPerson class]];     // 0
    
    
            * A : LGPerson元类
            * B : LGPerson类
            不相同,所以返回假
    

    3.2.2 对象方法调用例子

    1. - (BOOL)isKindOfClass:(Class)cls 方法分析

      • 方法调用格式
        [A isKindOfClass:B]

        • A-tcls 初始值:A的类
        • A-tcls 偏移值:A的类的父类
        • B-cls:用来做比较的类
      • 方法调用例子

        1. BOOL re5 = [(id)[NSObject alloc] isKindOfClass:[NSObject class]]; // 1

          • A : NSObject类
          • B : NSObject类
        2. BOOL re7 = [(id)[LGPerson alloc] isKindOfClass:[LGPerson class]]; // 1

          • A : LGPerson类/NSObject类
          • B : LGPerson类
    2. - (BOOL)isMemberOfClass:(Class)cls 方法分析

      • 方法调用格式
        [A isMemberOfClass:B]

        • A-self:A的类
        • B-cls:用来做比较的类
      • 方法调用例子

        1. BOOL re6 = [(id)[NSObject alloc] isMemberOfClass:[NSObject class]]; // 1

          • A : NSObject类
          • B : NSObject类
        2. BOOL re8 = [(id)[LGPerson alloc] isMemberOfClass:[LGPerson class]]; // 1

            * A : LGPerson类
            * B : LGPerson类
    

    相关文章

      网友评论

          本文标题:01--方法本质03--面试题分析

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