底层经典面试题

2020-09-15  本文已影响0人  旅行者_sz

前言:先来张熟悉又陌生的图:

isa流程图.png
【面试题一】iskindOfClass& isMemberOfClass 的理解
下面代码,怎么打印,并分析原因
int main(int argc, const char * argv[]) {
    @autoreleasepool {
      //-----使用 iskindOfClass & isMemberOfClass 类方法
BOOL re1 = [(id)[NSObject class] isKindOfClass:[NSObject class]];       //
BOOL re2 = [(id)[NSObject class] isMemberOfClass:[NSObject class]];     //
BOOL re3 = [(id)[LGPerson class] isKindOfClass:[LGPerson 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);  
//------iskindOfClass & isMemberOfClass 实例方法
BOOL re5 = [(id)[NSObject alloc] isKindOfClass:[NSObject class]];       //
BOOL re6 = [(id)[NSObject alloc] isMemberOfClass:[NSObject class]];     //
BOOL re7 = [(id)[LGPerson alloc] isKindOfClass:[LGPerson 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);
    }
    return 0;
}

打印如下:

re1 :1
re2 :0
re3 :0
re4 :0
re5:1
re6:1
re7:1
re8:1

结果已给,你细品,你细细的品;接下来,解释一波,有错,请留言,不要发红包。

源码分析一波

-isKindOfClass 源码解析(实例方法 & 类方法)

//--isKindOfClass---类方法、对象方法
//+ isKindOfClass:第一次比较是 获取类的元类 与 传入类对比,再次之后的对比是获取上次结果的父类 与 传入 类进行对比
+ (BOOL)isKindOfClass:(Class)cls {
   // 获取类的元类 vs 传入类
   // 根元类 vs 传入类
   // 根类 vs 传入类
   // 举例:LGPerson vs 元类 (根元类) (NSObject)
   for (Class tcls = self->ISA(); tcls; tcls = tcls->superclass) {
       if (tcls == cls) return YES;
   }
   return NO;
}

//- `isKindOfClass`:第一次是获取对象类 与 传入类对比,如果不相等,后续对比是继续获取上次 类的父类 与传入类进行对比
- (BOOL)isKindOfClass:(Class)cls {
/*
获取对象的类 vs 传入的类 
父类 vs 传入的类
根类 vs 传入的类
nil vs 传入的类
*/
   for (Class tcls = [self class]; tcls; tcls = tcls->superclass) {
       if (tcls == cls) return YES;
   }
   return NO;
}

//-----类方法
//+ isMemberOfClass : 获取类的元类,与 传入类对比
+ (BOOL)isMemberOfClass:(Class)cls {
    return self->ISA() == cls;
}
//-----实例方法
//- isMemberOfClass : 获取对象的类,与 传入类对比
- (BOOL)isMemberOfClass:(Class)cls {
    return [self class] == cls;
}

"强行解释一波"是有依据的,总结如下:
<article class="_2rhmJa">

案例代码执行结果分析

根据源码的分析,来分析代码执行的结果为什么是0或者1

使用类方法结果解析

使用实例方法结果解析

上一篇 下一篇

猜你喜欢

热点阅读