子类中的self和super

先上一段代码


在上述代码中,Dog是继承自NSObject。但是在Dog的初始化方法当中打印super class出现的竟然是Dog

因为OC是运行时机制,在运行时,self class相当于调用了runtime中给某一个对象发消息的C函数。给对象发消息有四种方式
1.objc_msgSend
2.objc_msgSend_stret
3.objc_msgSendSuper
4.objc_msgSendSuper_stret
在子类中调用self class方法时相当于调用了objc_msgSend这个方法。 第一个参数是消息接收者,第二个参数是调用的具体类方法的selector,后面是selector方法的可变参数。我们先不管这个可变参数,以 [self setName:]为例,编译器会替换成调用objc_msgSend的函数调用,其中theReceiver是self,theSelector是 @selector(setName:),这个selector是从当前self的class的方法列表开始找的setName,当找到后把对应的 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;
};
当使用 [self class] 时,这时的self是Dog,在使用objc_msgSend时,第一个参数是receiver也就是self,也是 Dog* dog这个实例。第二个参数,要先找到class这个方法的selector,先从Dog这个类开始找,没有,然后到Dog的父类 Father中去找,也没有,再去Father的父类NSObject去找,一层一层向上找之后,在NSObject的类中发现这个class方法,而 NSObject的这个class方法,就是返回receiver的类别,所以这里输出Dog。
当使用 [super class] 时,这时要转换成objc_msgSendSuper的方法。先构造objc_super的结构体吧,第一个成员变量就是self, 第二个成员变量是Father,然后要找class这个selector,先去superClass也就是Father中去找,没有,然后去Father 的父类中去找,结果还是在NSObject中找到了。然后内部使用函数objc_msgSend(objc_super->receiver, @selector(class)) 去调用,此时已经和我们用 [self class] 调用时相同了,此时的receiver还是Dog* dog,所以这里返回的也是Dog。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值