iOS Runtime

isKindOfClass和isMemberOfClass的区别

2020-09-20  本文已影响0人  木扬音

想要深入立即isKindOfClassisMemberOfClass的区别,那就离不开下面这个图

image.png

isa 走位链(两条)

superclass走位链(两条)

示例分享

//LGPerson 继承自 NSObject
BOOL re1 = [(id)[NSObject class] isKindOfClass:[NSObject class]];        
BOOL re2 = [(id)[LGPerson class] isKindOfClass:[LGPerson class]];    
BOOL re3 = [(id)[NSObject class] isMemberOfClass:[NSObject class]];         
BOOL re4 = [(id)[LGPerson class] isMemberOfClass:[LGPerson class]];     
NSLog(@" re1 :%hhd\n re2 :%hhd\n re3 :%hhd\n re4 :%hhd\n",re1,re2,re3,re4);

BOOL re5 = [(id)[NSObject alloc] isKindOfClass:[NSObject class]];    
BOOL re6 = [(id)[LGPerson alloc] isKindOfClass:[LGPerson class]];          
BOOL re7 = [(id)[NSObject alloc] isMemberOfClass:[NSObject class]];      
BOOL re8 = [(id)[LGPerson alloc] isMemberOfClass:[LGPerson class]];      
NSLog(@" re5 :%hhd\n re6 :%hhd\n re7 :%hhd\n re8 :%hhd\n",re5,re6,re7,re8);
输出
2020-09-20 21:15:13.975631+0800 KCObjc[2274:69804]  
 re1 :1
 re2 :0
 re3 :0
 re4 :0
2020-09-20 21:15:13.976631+0800 KCObjc[2274:69804]  
 re5 :1
 re6 :1
 re7 :1
 re8 :1

源码分析

+ (BOOL)isKindOfClass:(Class)cls

+ (BOOL)isKindOfClass:(Class)cls {
    for (Class tcls = self->ISA(); tcls; tcls = tcls->superclass) {
        // 获取类的元类 vs 传入类
        // 根元类 vs 传入类
        // 根类 vs 传入类
        if (tcls == cls) return YES;
    }
    return NO;
}
  • 传入的clsNSObject(根类)self 指向 NSObject,进入循环
  • tcls= NSObject meta(根元类),执行判断if (tcls == cls),不相等,进入下一个循环
  • tcls= NSObject(根类),执行判断if (tcls == cls),相等,return YES
  • 传入的clsLGPersonself 指向 LGPerson,进入循环
  • tcls= LGPerson meta(元类),执行判断if (tcls == cls),不相等,进入下一个循环
  • tcls= NSObject meta(根元类),执行判断if (tcls == cls),不相等,进入下一个循环
  • tcls= NSObject meta(根类),执行判断if (tcls == cls),不相等,进入下一个循环
  • tcls= nil,结束循环,

+ (BOOL)isMemberOfClass:(Class)cls

+ (BOOL)isMemberOfClass:(Class)cls {
    //获取类的元类,与 传入类对比
    return self->ISA() == cls;
}
  • 传入的clsNSObject(根类)self 指向 NSObject,进入循环
  • tcls= NSObject meta(根元类),执行判断if (tcls == cls),不相等
  • 传入的clsLGPersonself 指向 LGPerson,进入循环
  • tcls= NSObject meta(元类),执行判断if (tcls == cls),不相等

- (BOOL)isKindOfClass:(Class)cls

- (BOOL)isKindOfClass:(Class)cls {
    //获取对象的类 vs 传入的类 
    //父类 vs 传入的类
    //根类 vs 传入的类
    for (Class tcls = [self class]; tcls; tcls = tcls->superclass) {
        if (tcls == cls) return YES;
    }
    return NO;
}
  • 传入的clsNSObject(根类)self 指向 NSObject实例对象,进入循环,NSObject实例对象的isa即NSObject(根类)
  • tcls= NSObject(根类),执行判断if (tcls == cls),相等
  • 传入的clsLGPersonself 指向 LGPerson实例对象,进入循环,LGPerson实例对象的isa即LGPerson
  • tcls= LGPerson,执行判断if (tcls == cls),相等

- (BOOL)isMemberOfClass:(Class)cls

- (BOOL)isMemberOfClass:(Class)cls {
    //获取对象的类,与 传入类对比
    return [self class] == cls;
}
  • 传入的clsNSObject(根类)self 指向 NSObject实例对象,进入循环,NSObject实例对象的即NSObject(根类)
  • tcls= NSObject(根类),执行判断if (tcls == cls),相等
  • 传入的clsLGPersonself 指向 LGPerson实例对象,进入循环,LGPerson实例对象的即LGPerson
  • tcls= LGPerson,执行判断if (tcls == cls),相等

总结

isKindOfClass

  • 类方法:元类的继承链对比
    • 元类(isa) --> 根元类(父类) --> 根类(父类) --> nil(父类)
  • 实例方法:对象的类 --> 父类 --> 根类 --> nil传入类的对比

isMemberOfClass

  • 类方法: 类的元类传入类 对比
  • 实例方法:对象的父类传入类 对比
上一篇下一篇

猜你喜欢

热点阅读