iOS—[self class]和[super class]

先上一段代码
Person类继承NSObject
Student类继承Person

//Person类 继承自NSObject
#import <Foundation/Foundation.h>

@interface Person : NSObject

@end

#import "Person.h"

@implementation Person

@end


//Student类 继承自Person
#import "Person.h"

NS_ASSUME_NONNULL_BEGIN

@interface Student : Person


- (void)test;

@end


#import "Student.h"

@implementation Student

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

@end


//main中 
#import <Foundation/Foundation.h>
#import "Student.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // insert code here...
        NSLog(@"Hello, World!");
        
        Student *stu = [[Student alloc] init];
        
        [stu test];
       
    }
    return 0;
}

main函数中,执行Student中的test方法
在这里插入图片描述
打印结果如下
在这里插入图片描述
对于打印的[self class]、[self superclass]的结果我们并不意外

当我们调用[self class],编译器会将其转化为objc_msgSend(self,@selector(class)),消息的接受者就是当前所在类的实例对象,这个时候就会去self所在的类里找class实例方法,如果没有找到就会去Student的父类Person类中去找class方法,如果还是找不到就会从Person的父类NSObject类去找class方法。(即沿着继承链找)
最终找到了class方法,class方法里返回了object_getClass(self),即返回了方法调用者所属的类。

调用[self superclass]的过程里和上述类似。

class与superclass在NSObject类中的实现如下:

在这里插入图片描述

前两个我们都清楚结果

奇怪的是[super class]、[super superclass]

将test方法转为c++,代码如下
在这里插入图片描述

//简化看一下 这里删去NSLog部分 

//[self class];
objc_msgSend(self, sel_registerName("class");

//[self superClass];
objc_msgSend(self, sel_registerName("superclass")
  
//[super class];  
objc_msgSendSuper((__rw_objc_super){
									self, 
									class_getSuperclass(objc_getClass("Student"))
									}, 
				 					sel_registerName("class"));


//[super superClass];
objc_msgSendSuper((__rw_objc_super){
									self, 
									class_getSuperclass(objc_getClass("Student"))
									}, 
									sel_registerName("superclass"));

下面会分别来讲一下

[super class]

//[super class]转为c++

objc_msgSendSuper((__rw_objc_super){
									self, 
									class_getSuperclass(objc_getClass("Student"))
									}, 
				 					sel_registerName("class"));


//与self不一样的是调用的是objc_msgsendSuper函数

//第一个参数是objc_super结构体类型 
//查看该结构体的定义可知 第一个参数是方法调用者(消息接受者)self,第二个参数是实例的父类

struct objc_super {

    __unsafe_unretained _Nonnull id receiver;      //消息接受者

    __unsafe_unretained _Nonnull Class super_class;   //消息接受者的父类

};

我们再看一下msgSendSuper函数的定义
在注释中我们可以看到第一个参数,…包含了接收消息的类的实例和开始搜索方法实现的超类…。

在这里插入图片描述
也就是说调用[super class],方法的接受者还是self,但是我们查找class方法是从当前类的父类开始查找,如果当前类的父类Person中没有找到class方法,那么就会去Person类的父类NSObject中找class方法。
由于NSObject类中的class方法返回值为方法调用者所属的类,即self所属的类,所以[super class]的返回值还是为Student。

[super superclass]的过程也与上述类似。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值