self和super的关系

我们都知道self是指向当前调用者的指针,那么super呢?
有的同学会说平时用super调用父类的方法,会说这是指向父类的指针,其实不是的,super仅仅是一个编译器的指示器,就是给编译器看的,不是一个指针;本质还是当前对象的调用者(self),只要编译器看到super这个标志就会让当前对象去调用父类方法。接下来使用几个示例class、superClass和使用clang编译指令来查看编译或代码示例来证明:

先定义两个类Persion,SubPersion,其中SubPersion继承Persion。现在SubPersion中定义并实现test方法。如下示例

#import "SubPersion.h"

@implementation SubPersion
-(void)test{
    NSLog(@"%@ %@ %@ %@",[self class],[self superclass],[super class],[super superclass]);
}
@end

打印的日志如下。
在这里插入图片描述
解下来在父类中实现test,再子类调用test

#import "Persion.h"

@implementation Persion
-(void)test{
    NSLog(@"%@ %@ %@ %@",[self class],[self superclass],[super class],[super superclass]);
}
@end
#import "SubPersion.h"

@implementation SubPersion
-(void)test{
    [super test];
}
@end

在这里插入图片描述
通过两个例子的日志打印,可看出,super不是指向父类的指针,只是一个编译器指示器,实现还是当前调用者self

下面通过将下列代码使用clang -rewrite-objc命令编译,看编译后的的代码

#import <Foundation/Foundation.h>
@interface Persion : NSObject

@end
@implementation Persion
- (NSString *)description
{
    return [super description];
}
@end


int main(int argc, const char * argv[]) {
    @autoreleasepool {
    
    }
    return 0;
}

转换后我们看这段代码如下。

static NSString * _I_Persion_description(Persion * self, SEL _cmd) {
    return ((NSString *(*)(__rw_objc_super *, SEL))(void *)objc_msgSendSuper)((__rw_objc_super){(id)self, (id)class_getSuperclass(objc_getClass("Persion"))}, sel_registerName("description"));
}
// @end


int main(int argc, const char * argv[]) {
    /* @autoreleasepool */ { __AtAutoreleasePool __autoreleasepool; 

    }
    return 0;
}

将强制转换去出后代码如下

static NSString * _I_Persion_description(Persion * self, SEL _cmd) {
    return objc_msgSendSuper({(self, class_getSuperclass(objc_getClass("Persion"))}, sel_registerName("description"));
}```
通过查看objc_msgSendSuper方法的源码可看出第一个参数是结构图objc_super,而结构体定义如下

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 */
};

结构体的第一个参数为消息发送者,而第二个参数表明为父类,通过编译后看出,发送消息是self。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值