OC追根溯源之Class

简介: 前两天碰到一面试题://分辨下面res的是非BOOL res1 = [[NSObject class] isKindOfClass:[NSObject class]];BOOL res2 = [[NSObject class] isMemberO...

前两天碰到一面试题:

//分辨下面res的是非
BOOL res1 = [[NSObject class] isKindOfClass:[NSObject class]];
BOOL res2 = [[NSObject class] isMemberOfClass:[NSObject class]];
BOOL res3 = [[Sark class] isKindOfClass:[Sark class]];
BOOL res4 = [[Sark class] isMemberOfClass:[Sark class]];

在这之前,我们先了解一下相关的定义:

Class

objc.hClass是这么定义的:

/// An opaque type that represents an Objective-C class.
typedef struct objc_class *Class;

objc_class又是啥呢?在runtime.h中能看见:

struct objc_class {
    Class isa  OBJC_ISA_AVAILABILITY;

#if !__OBJC2__
    Class super_class                                        OBJC2_UNAVAILABLE;
    const char *name                                         OBJC2_UNAVAILABLE;
    long version                                             OBJC2_UNAVAILABLE;
    long info                                                OBJC2_UNAVAILABLE;
    long instance_size                                       OBJC2_UNAVAILABLE;
    struct objc_ivar_list *ivars                             OBJC2_UNAVAILABLE;
    struct objc_method_list **methodLists                    OBJC2_UNAVAILABLE;
    struct objc_cache *cache                                 OBJC2_UNAVAILABLE;
    struct objc_protocol_list *protocols                     OBJC2_UNAVAILABLE;
#endif

} OBJC2_UNAVAILABLE;

MetaClass

上面能看到Class中有个isa参数,它是指向Class元类(MetaClass)的指针。

注意到isa也是一个Class的结构体,也就是说MetaClass其本质也是一个Class

我们可以把Meta Class理解为 一个Class对象的Class。简单的说:

  • 当我们发送一个消息给一个NSObject对象时,这条消息会在对象的类的方法列表里查找
  • 当我们发送一个消息给一个类时,这条消息会在类的Meta Class的方法列表里查找

之后就有了下面的这张图:

ocClass.jpg

能看到:

  • 每个Class都有一个isa指针指向一个唯一的MetaClass
  • 每一个MetaClassisa指针都指向最上层的MetaClass(图中的NSObjectMetaClass
  • 最上层的MetaClassisa指针指向自己,形成一个回路
  • 每一个MetaClasssuper class指针指向它原本ClassSuper ClassMetaClass
  • 最上层的MetaClassSuper Class指向NSObject Class本身
  • 最上层的NSObject Classsuper class指向 nil

接下来我们看看objc源码中,在文件Object.mm内,上面相关方法的定义:

+ (Class)class {  
    return self;  
}
- (BOOL)isKindOf:aClass
{
    Class cls;
    for (cls = isa; cls; cls = cls->superclass)
        if (cls == (Class)aClass)
            return YES;
    return NO;
}
- (BOOL)isMemberOf:aClass
{
    return isa == (Class)aClass;
}

那么,BOOL res1 = [[NSObject class] isKindOfClass:[NSObject class]];就可以这样对应起来理解了:

[NSObject class]拿到的是self,类方法的return self,即上图紫色的NSObject(Class)

根据上面- (BOOL)isKindOf:aClass的实现,for循环首先拿到的cls = isa,也就是clsNSObject(Class)MetaClass。显然这时候cls == (Class)aClass不成立。

随后,cls = cls->superclass,即cls变成了NSObject(Class)MetaClasssuperclass,根据图示可以,superclass指向的是NSObject(Class),至此cls == (Class)aClass成立,返回YES

同样的道理,分析BOOL res3 = [[Sark class] isKindOfClass:[Sark class]];:

[Sark class]拿到的是Sark(Class),而- (BOOL)isKindOf:aClasscls拿到的值依次是Sark Meta Class->NSObject Meta Class->NSObject Class -> nil,没有相等的,return NO

剩下两个,根据- (BOOL)isMemberOf:aClass的实现,很容易得出结论会return NO

目录
相关文章
|
9月前
|
人工智能 运维 Cloud Native
云原生 Meetup,AI 应用工程化专场·广州站
欢迎莅临广州市海珠区鼎新路 88 号广州阿里中心,O-N-10-02 春秋书院。报名成功后,您将在活动前一周收到短信通知。
149 96
|
机器学习/深度学习 人工智能 搜索推荐
《百炼成金-大金融模型新篇章》––09.金融级AI原生的发展
百炼必定成金,新质生产力会催生新质劳动力,谨以此文抛砖引玉,希望与业内的各位朋友一同探讨如何积极拥抱并运用大模型技术,以应对和驾驭不断变化的市场环境,实现科技金融持续稳定的提质增效和创新发展,携手开启金融大模型未来新篇章。
254 3
|
存储 安全 网络安全
云计算的双刃剑:机遇与网络安全挑战
随着云计算技术的飞速发展,企业与个人用户纷纷投身于云服务的怀抱,享受其带来的便捷与高效。然而,在云端的数据海洋中,网络安全问题如影随形,成为制约云服务发展的隐形枷锁。本文深入探讨了云计算环境下的网络安全挑战,分析了云服务模式中的安全风险,并提出了相应的信息安全策略,以期为云计算的健康发展提供参考。
160 5
|
人工智能 搜索推荐 数据安全/隐私保护
别错过!2024年苹果iPhone AI革命:揭秘技术突破与未来蓝图
本文首发于公众号“AntDream”。2024年,苹果iPhone在技术创新方面展现了一系列亮点,包括Apple Intelligence集成、Siri的进化、系统范围的写作工具、图像生成能力、跨应用任务处理、隐私保护加强等。iOS 18带来了多项改进,如屏幕图标重新设计、新增卫星短信等功能。后续规划包括Apple Intelligence的推广、与其他AI模型合作、硬件发展、软件生态扩展、全球多语言支持等。苹果将继续优化用户体验和强化隐私保护,探索AI技术在健康监测、增强现实等领域的应用,持续引领智能手机领域的创新潮流。
708 1
|
运维
老司机,思路就是清晰!Eth-Trunk无法转发流量竟然是这样定位的!
老司机,思路就是清晰!Eth-Trunk无法转发流量竟然是这样定位的!
171 0
|
图形学
【制作100个unity游戏之27】使用unity复刻经典游戏《植物大战僵尸》,制作属于自己的植物大战僵尸随机版和杂交版4(附带项目源码)
【制作100个unity游戏之27】使用unity复刻经典游戏《植物大战僵尸》,制作属于自己的植物大战僵尸随机版和杂交版4(附带项目源码)
240 0
|
移动开发 UED HTML5
HTML锚点链接的深入解析与应用
HTML锚点链接的深入解析与应用
692 0
|
Web App开发 JavaScript 前端开发
Element-ui 滚动条美化
有时候为了使界面滚动条,各个浏览器的滚动条能保持一致,这样我们的项目避免在各个浏览器存在差异导致UI界面的不一致,这时候我们就可以考虑使用通用组件的方式,对各个需要滚动的页面,或者弹出窗口添加统一的组件进行包裹,来保证滚动效果在各个浏览器中能有更好的体验效果。最后我们看到各个浏览器中滚动条的效果,基本上各个浏览器的表现效果是一致的,添加通用组件,默认情况下滚动条是不显示的,只有鼠标移动过去才会进行显示,整体上效果和用户体验会更好。在源码顶部,看到有一个链接地址,是参考另一个插件的实现,如下所示。
Element-ui 滚动条美化
|
网络安全
解决win10下WinSCP老是断线重连
解决win10下WinSCP老是断线重连
|
机器学习/深度学习 人工智能 算法
论文推荐:ScoreGrad,基于能量模型的时间序列预测
能量模型(Energy-based model)是一种以自监督方式执行的生成式模型,近年来受到了很多关注。本文将介绍ScoreGrad:基于连续能量生成模型的多变量概率时间序列预测。如果你对时间序列预测感兴趣,推荐继续阅读本文。
488 0