美文网首页
理解 Self & Super

理解 Self & Super

作者: geekAppke | 来源:发表于2018-03-28 09:29 被阅读20次

下面会打印什么?

- (id)init {
    self = [super init];
    if (self)
    {
        NSLog(@"%@", NSStringFromClass([self class]));
        NSLog(@"%@", NSStringFromClass([super class]));
    }
    return self;
 }
 @end
self:当前这个对象
super:编译器标示符,给编译器看的,底层用另外一个方法发消息
super就是self,去调用父类方法
让当前对象调用父类方法,本质上还是self在调用
  • 无论是[self class]还是[super class],接受消息者都是Son对象
    • super与self不同的是,self调用是在子类Son中找class方法
    • super调用是在父类Father中找class方法
  • 编译后,调用super标识符修饰的方法,会用objc_msgSendSuper函数进行消息的发送,而不是objc_msgSend

深度解析

调用[self class]方法时

  • 转化为objc_msgSend函数
  • 先在 Son 这个类里面去找- (Class)class方法,没有就去父类 Father里找,也没有,最后在 NSObject类中发现这个方法
NSObject类中- (Class)class的实现如下:
- (Class)class {
    // 返回实例的isa指针指向的类
    return object_getClass(self);
} 

[self class] == objc_msgSend(self, "class");
打印:Son

调用[super class]方法时

  • super为编译器标示符
  • 向super发送的消息被编译成objc_msgSendSuper
  • 不管是self、还是super指向消息接受者是一样的
转化为objc_msgSendSuper,函数定义如下:
id objc_msgSendSuper(struct objc_super *super, SEL op, ...) 
// objc_super的结构体
struct objc_super {
    id receiver;     
    Class super_class; // 记录当前父类
}; 
  • receiver,类的实例
    • objc_super->receiver=self
    • 消息的接受者还是self
  • super_class,记录当前类的父类
    • (id)class_getSuperclass(objc_getClass(“Son”))
      • 该函数输出结果为 Father
    • 去 Father这个类里去找- (Class)class,没有,然后去NSObject类去找
  • super只是告诉编译器,去查找父类中的class方法
    • 当找到之后,使用objc_super->receiver即self进行调用
[super class]转换流程

[super class] → objc_msgSendSuper(objc_super{self, superclass}, sel_registerName("class")) → objc_msgSend(objc_super->self, sel_registerName("class")) === [self class]
打印:Son


demo2:理解super

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

/**
  class:获取方法调用者类名
  superclass:获取方法调用者的父类类名
  super:指向父类的标识,编译器修饰符,不是指针
 */
- (void)test
{
    // 谁调用这个方法,self就是谁!
    NSLog(@"%@", self);
//    NSLog(@"%@", super);
    // 函数里也没有定义super
    // self是隐藏参数,super就是个标识符,和const差不多!
//    NSLog(@"%@, %@, %@", [self class], [self superclass], [super class]);
    // Son, Father, Son
    
    [super test];
    // Son, Father, Son
}
@end
super不是父类对象!!
  • 和const差不多
  • self是对象、是指针可以打印,super不是指针,不能打印
  • 本质还是拿到当前对象去调用父类方法
  • super就是self去调用父类方法
  • 只是去父类方法里找,而不是找自己的

参考资料

相关文章

  • 理解 Self & Super

    下面会打印什么? 无论是[self class]还是[super class],接受消息者都是Son对象super...

  • @property`self & super

    @property 之前每声明一个实例变量都要进行设置响应的set /get 方法;通过property来声明可以...

  • self、 superclass 、 super的区别

    self、 superclass 、 super的区别 self、 superclass 、 super self...

  • python之理解super及MRO列表

    python之理解super type 类。 object-or-type 类,一般是 self。 1、super...

  • super

    示例 self [self class]、[self superclass]调用流程 super [super c...

  • iOS self&super

    self和super区别 self 是关键字 代表当前方法的调用者如果是类方法:代表当前类如果是对象方法:代表当前...

  • Runtime ——self&super

    下面的代码输出什么? @implementation Son : Father - (id)init { self...

  • self和super的区别

    self和super的区别 self调用自己方法,super调用父类方法 self是类,super是预编译指令 [...

  • self和super的理解

    下面代码输出的是什么: 答案: 都是Son。 self 是类的隐藏参数,指向当前调用方法的这个类的实例。而 sup...

  • self和super的理解

    下面的代码输出什么?@implementation Son : Father - (id)init { self ...

网友评论

      本文标题:理解 Self & Super

      本文链接:https://www.haomeiwen.com/subject/pezecftx.html