前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >[self class] 与 [super class]

[self class] 与 [super class]

作者头像
网罗开发
发布于 2021-01-29 08:45:01
发布于 2021-01-29 08:45:01
42600
代码可运行
举报
文章被收录于专栏:网罗开发网罗开发
运行总次数:0
代码可运行

首先先看一段代码,看到下面代码输入是什么?

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@implementation Son : Father
- (id)init {
    self = [super init];
    if (self) {
        NSLog(@"%@", NSStringFromClass([self class]));
        NSLog(@"%@", NSStringFromClass([super class]));
    }
    return self;
}
@end

运行结果:Son Son

看到运行结果,应该相当一部分的人认为是 Son Father.

[self class]、[super class]内部实现

为啥是 [super class] 是 Son ,那我们就分析一下整个流程:

当 [self class] 、 [super class] 调用的是 -(Class)calss,但是 [self class]、[super class] 都没有实现 -(Class)class,通过消息传递一直会找到基类NSObject 中,并且找到 -(Class)class 实现,可以在 NSObject.m 中找到这个方法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
- (Class)class {
    return object_getClass(self);
}

object_getClass 这个方法是获取当前对象的类对象。看看 object_getClass 内部实现

在 runtime 文件中可以找 objc_class.m 找到 object_getClass 的实现:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Class object_getClass(id obj) {
    if (obj) return obj->getIsa();
    else return Nil;
}

最终这个方法还是通过 obj 的 isa 指针,找到当前的对象的类对象。

我们可以 clang -rewrite-objc 命令将下面

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
NSLog(@"%@", NSStringFromClass([self class]));
NSLog(@"%@", NSStringFromClass([super class]));

转换成:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
NSLog((NSString *)&__NSConstantStringImpl__var_folders_8k_cgm28r0d0bz94xnnrr606rf40000gn_T_Car_3f2069_mi_0, NSStringFromClass(((Class (*)(id, SEL))(void *)objc_msgSend)((id)self, sel_registerName("class"))));

NSLog((NSString *)&__NSConstantStringImpl__var_folders_8k_cgm28r0d0bz94xnnrr606rf40000gn_T_Son_3f2069_mi_1, NSStringFromClass(((Class (*)(__rw_objc_super *, SEL))(void *)objc_msgSendSuper)((__rw_objc_super){(id)self, (id)class_getSuperclass(objc_getClass("Son"))}, sel_registerName("class"))));

clang 之后代码看出,调用 [super class] 的时候本质是调用:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
objc_msgSendSuper(struct objc_super *super, SEL op, ...)

查看一下 objc_super 的定义如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
struct objc_super {
    /// Specifies an instance of a class.
    __unsafe_unretained _Nonnull id receiver;

    /// Specifies the particular superclass of the instance to message. 
#if !defined(__cplusplus)  &&  !__OBJC2__
    /* For compatibility with old objc-runtime.h header */
    __unsafe_unretained _Nonnull Class class;
#else
    __unsafe_unretained _Nonnull Class super_class;
#endif
    /* super_class is the first class to search */
};

objc_super 内部结构可以看出,只要编译器看到出现 super 这个标志,就会让当前对象不管本类有没有实现都是去父类去找该方法,super就仅仅是一个编译指示器。 但是消息的接受还是 self,最终在 NSObject 获取 isa 指针的时候获取的还是 self 的 isa,执行的类对象还是 Son。

结尾

  1. [super class] 中的 super 只是一个编译指示器,就是让当前对象获取该方法,越过本类,直接从父类找。
  2. 消息的接受者还是本类 self。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-01-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 网罗开发 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Runtime学习:面试题狙击
前面两篇文章分别记录了自己学习 Runtime 的一些知识点以及常见的一些应用。之前立下 flag 说准备写三篇关于 Runtime 的文章,于是就有了这篇文章。
iOSSir
2019/06/21
5610
[super class]和[self class]
按照我们的常规理解,super对应的应该打印Parent啊,为啥最后打印的是Son呢?
拉维
2019/11/21
6750
[super class]和[self class]
深入浅出 Runtime(四):super 的本质
我们先来看两个数据结构objc_super和objc_super2。 它们的区别在于第二个成员: objc_super:super_class // receiverClass 的父类 objc_super2:current_class // receiverClass(消息接收者的class对象)
师大小海腾
2020/04/16
1.6K0
A interesting inheritance question between self and super
Here is a inheritance chain relationship: NSObject -> RootCls -> SubCls Think About a question? What
Mitchell
2018/09/30
3890
iOS开发·runtime原理与实践: 基本知识篇(类,超类,元类,super_class,isa,对象,方法,SEL,IMP)
Tips:苹果公开的源代码在这里可以查,https://opensource.apple.com/tarballs/
陈满iOS
2018/09/10
1.8K1
iOS开发·runtime原理与实践: 基本知识篇(类,超类,元类,super_class,isa,对象,方法,SEL,IMP)
iOS开发·KVO用法,原理与底层实现: runtime模拟实现KVO监听机制(Blcok及Delgate方式)
KVO 是 Objective-C 对 观察者模式(Observer Pattern)的实现。当被观察对象的某个属性发生更改时,观察者对象会获得通知。有意思的是,你不需要给被观察的对象添加任何额外代码,就能使用 KVO 。这是怎么做到的?
陈满iOS
2018/09/10
2.1K0
iOS开发·KVO用法,原理与底层实现: runtime模拟实现KVO监听机制(Blcok及Delgate方式)
objc_msgSend 实现分析
Runtime 有两个版本:Legacy 版本(早期版本,对应 Objective-C 1.0) 和 Modern 版本(现行版本 Objective-C 2.0)。
网罗开发
2021/07/21
9390
iOS底层原理之Runimte 运行时&方法的本质
前面探究了类里面的重要的变量,iOS 底层原理之cache分析分析了缓存方法调用流程。
CC老师
2022/01/11
4140
iOS底层原理之Runimte 运行时&方法的本质
OC底层探索10-objc_msgSend快速查找流程OC底层探索10-objc_msgSend快速查找流程
****总结:调用->方法快速查找->方法慢速查找->方法动态决议**** 每一步都会进行分步解释。
用户8893176
2021/08/09
4200
OC底层探索10-objc_msgSend快速查找流程OC底层探索10-objc_msgSend快速查找流程
iOS底层原理总结 - 探寻Runtime本质(四)
首先来看一道面试题。 下列代码中Person继承自NSObject,Student继承自Person,写出下列代码输出内容。
xx_Cc
2018/08/02
9350
iOS底层原理总结 - 探寻Runtime本质(四)
面经之《招聘一个靠谱的iOS》import "CYLBlockExecutor.h"import "CYLBlockExecutor.h"import "CYLNSObject+RunAtDeallo
什么情况使用 weak 关键字,相比 assign 有什么不同? 什么情况使用 weak 关键字? 在 ARC 中,在有可能出现循环引用的时候,往往要通过让其中一端使用 weak 来解决,比如: de
rectinajh
2018/05/17
1.1K0
神经病院Objective-C Runtime入院第一天—isa和Class
我第一次开始重视Objective-C Runtime是从2014年11月1日,@唐巧老师在微博上发的一条微博开始。
一缕殇流化隐半边冰霜
2018/08/30
8140
神经病院Objective-C Runtime入院第一天—isa和Class
消息转发及super
**消息转发的时候。由于oc的底层原理是消息机制,所以可以添加c语言函数等 **
老沙
2019/09/28
6330
OC对象模型
可以看出,alloc类方法是开辟了一块内存,生成了一个实例对象,并且对实例对象进行了初始化
Helloted
2022/06/06
6800
OC对象模型
透彻理解 KVO 观察者模式(附基于runtime实现代码)
推荐另一篇文章:透彻理解 NSNotificationCenter 通知(含实现代码)
波儿菜
2018/05/07
1K0
动态的Objective-C——关于消息机制与运行时的探讨
    Objective-C是一种很优美的语言,至少在我使用其进行编程的过程中,是很享受他那近乎自然语言的函数命名、灵活多样的方法调用方式以及配合IDE流顺畅快编写体验。Objective-C是扩展与C面向对象的编程语言,然而其方法的调用方式又和大多面向对象语言大有不同,其采用的是消息传递、转发的方式进行方法的调用。因此在Objective-C中对象的真正行为往往是在运行时确定而非在编译时确定,所以Objective-C又被称为是一种运行时的动态语言。
珲少
2018/08/15
8410
动态的Objective-C——关于消息机制与运行时的探讨
OC - Block 详解
通过 Clang 将以下 Block 代码转换为 C++ 代码,来分析 Block 的底层实现。
师大小海腾
2020/04/16
3.2K0
OC - Block 详解
iOS runtime探究(二): 从runtime开始深入理解OC消息转发机制你要知道的runtime都在这里
你要知道的runtime都在这里 转载请注明出处 https://cloud.tencent.com/developer/user/1605429 本文主要讲解runtime相关知识,从原理到实践,由于包含内容过多分为以下五篇文章详细讲解,可自行选择需要了解的方向: 从runtime开始: 理解面向对象的类到面向过程的结构体 从runtime开始: 深入理解OC消息转发机制 从runtime开始: 理解OC的属性property 从runtime开始: 实践Category添加属性与黑魔法method sw
WWWWDotPNG
2018/04/10
9680
iOS runtime探究(二): 从runtime开始深入理解OC消息转发机制你要知道的runtime都在这里
[Objective-C Runtime] 类与对象
概述 常说Objective-C是一门动态语言,那么问题来了,这个动态表现在那些方面呢? 其实最主要的表现就是Objective-C将很多静态语言在编译和链接时做的事情放到了运行时去做。 它在运行时实现了对类、方法、成员变量、属性等信息的管理机制,同时,运行时机制为我们开发过程提供很多便利之处,比如: 在运行时创建或者修改一个类; 在运行时修改成员变量、属性等; 在运行时进行消息分发和分发绑定; ...... 与之对应实现的就是Objective-C的Runtime机制。 Runtime基本是C和汇编编写的
Jacklin
2018/05/15
9380
KVO详解(二)
上篇文章中我介绍了KVO的简单用法以及KVO的实现细节,为了加深对KVO的理解,我决定从头到尾介绍一下如何自定义KVO。
拉维
2021/03/25
7370
KVO详解(二)
推荐阅读
相关推荐
Runtime学习:面试题狙击
更多 >
领券
💥开发者 MCP广场重磅上线!
精选全网热门MCP server,让你的AI更好用 🚀
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档