[self class] 与 [super class]

前提

面试的时候会不会问到类似的问题:类ClassB继承于类ClassA,这时候在类ClassB的方法中分别打印[self class] 与 [super class]会输出什么?

实践出真知:

有没有被惊艳到?[super class]不应该是ClassA吗?请往下看

Self关键字与Super关键字

    self 是类的隐藏的参数,指向当前调用方法的类,另一个隐藏参数是_cmd,代表当前类方法的selector。这里只关注这个self。

    super并不是隐藏的参数,它只是一个“编译器指示符”,它和self指向的是相同的消息接收者。不同的是,super告诉编译器,要去调用父类的方法而不是本类里的,super只是指示符的作用没有实际意义。

    当使用self调用方法时,会从当前类的方法列表中开始找,如果没有,就从父类中再找;而当使用super时,则从父类的方法列表中开始找。然后调用父类的这个方法。

实现机制

apple的objcRuntimeRef 上说:

Sending Messages

When it encounters a method invocation, the compiler might generate a call to any of several functions to perform the actual message dispatch, depending on the receiver, the return value, and the arguments. You can use these functions to dynamically invoke methods from your own plain C code, or to use argument forms not permitted by NSObject’sperform...methods. These functions are declared in/usr/include/objc/objc-runtime.h.

objc_msgSend sends a message with a simple return value to an instance of a class.

objc_msgSend_stret sends a message with a data-structure return value to an instance of a class.

objc_msgSendSuper sends a message with a simple return value to the superclass of an instance of a class.

objc_msgSendSuper_stret sends a message with a data-structure return value to the superclass of an instance of a class.

我们只关注objc_msgSend和objc_msgSendSuper两个方法。

当使用[self class]调用时,会使用objc_msgSend的函数,先看下objc_msgSend的函数定义:

id objc_msgSend(id theReceiver, SEL theSelector, ...)

第一个参数是消息接收者,第二个参数是调用的具体类方法的selector,后面是selector方法的可变参数。

以 [self class]为例,编译器会替换成调用objc_msgSend的函数调用,其中theReceiver是self,theSelector是 @selector(class),这个selector是从当前self的class的方法列表开始找的@selector(class),当找到后把对应的 selector传递过去。

而当使用[super class]调用时,会使用objc_msgSendSuper函数,看下objc_msgSendSuper的函数定义:

id objc_msgSendSuper(struct objc_super *super, SEL op, ...)

第一个参数是个objc_super的结构体,第二个参数还是类似上面的类方法的selector,先看下objc_super这个结构体是什么东西:

struct objc_super {

id receiver;

Class superClass;

};

可以看到这个结构体包含了两个成员,一个是receiver,这个类似上面objc_msgSend的第一个参数receiver,第二个成员是记 录写super这个类的父类是什么

拿上面的代码为例,当编译器遇到ClassB中init方法里的[super class]时,开始做这几个事:

1,构建objc_super的结构体,此时这个结构体的第一个成员变量receiver就是ClassB的实例,和self相同。而第二个成员变量superClass就是指类ClassA,因为ClassB的超类就是这个ClassA。

2,调用objc_msgSendSuper的方法,将这个结构体和class方法传递过去。函数里面在做的事情类似这样:从 objc_super结构体指向的superClass的方法列表开始找class的selector,找到后再以 objc_super->receiver去调用这个selector,可能也会使用objc_msgSend这个函数,不过此时的第一个参数 theReceiver就是objc_super->receiver,第二个参数是从objc_super->superClass中找到的selector,源代码汇编核心代码大概是这个意思

ENTRY _objc_msgSendSuper

MESSENGER_START

ldr r9, [r0, #CLASS] // r9 = struct super->class

CacheLookup NORMAL

// cache hit, IMP in r12, eq already set for nonstret forwarding

ldr r0, [r0, #RECEIVER] // load real receiver 在这里直接加载真实的receiver

MESSENGER_END_FAST

bx r12 // call imp

CacheLookup2 NORMAL

// cache miss

ldr r9, [r0, #CLASS] // r9 = struct super->class

ldr r0, [r0, #RECEIVER] // load real receiver  在这里直接加载真实的receiver

MESSENGER_END_SLOW

b __objc_msgSend_uncached

END_ENTRY _objc_msgSendSuper

里面的调用机制大体就是这样了

由此可以知道,为什么[self class]与[super class]打印结果相同了吧


参考内容:

Apple 之《objc4

南峰子的技术博客之《Objective-C Runtime 运行时之一:类与对象

Loving_iOS之《iOS经典讲解之[self class]和[super class]的区别

GSChan之《iOS中self与super

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,558评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,002评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,036评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,024评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,144评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,255评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,295评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,068评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,478评论 1 305
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,789评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,965评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,649评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,267评论 3 318
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,982评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,223评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,800评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,847评论 2 351

推荐阅读更多精彩内容