self、super 和 class、superclass 的组合

一、创建类

  • Person 类:继承至 NSObject 类
  • SubPerson 类:继承至 Person 类
  • Person 类中有一个对象方法 test
  • SubPerson类中实现此方法,并在此方法中写
    • [self class]
    • [self superclass]
    • [super class]
    • [super superclass]
  • 外界调用 subPerson 的 test 方法。

代码如下:

Person.h
@interface Person : NSObject
- (void)test;
@end


SubPerson.m
#import "SubPerson.h"
@implementation SubPerson
- (void)test {
    NSLog(@"SubPerson - test");
   
   // 打印结果:SubPerson - Person - SubPerson - Person
    NSLog(@"%@ - %@ - %@ - %@", [self class], [self superclass], [super class], [super superclass]);
}
@end

二、解释 SubPerson 类中的self、super 、 class、superclass

  • class: 获取当前方法调用者的类

  • superclass: 获取当前方法调用者的父类

  • self: 当前类,是一个指针

  • super: 仅仅是一个编译指示器,只是给编译器看的,不是一个指针

  • super的本质:当编译器看到 super 这个标志,就会让当前对象去调用父类的方法,本质还是当前对象在调用。

  • 如何判断 super 不是一个指针? 打印一下就知道了。指针是可以打印的。

  // 不报错
  NSLog(@"%@",self);

  // 报错:Use of undeclared identifier 'super' - 没有定义 super
  NSLog(@"%@",super);
     

三、在subPerson 类的test方法调用 [super test];

  • subPerson 类的test方法调用 [super test];
  • Person 类的 test 方法中写入代码 NSLog(@"%@ - %@ - %@ - %@", [self class], [self superclass], [super class], [super superclass]);
  • 打印结果为:SubPerson - Person - SubPerson - Person

这是因为:

  • subPerson 类中的[super test]super 相当于self。(如不记得,请看二中的super定义)。
  • 所以 person 类 中打印的相当于 subperson 类的打印。

四、super 的底层实现

  1. 创建命令行项目 macOS -> Application -> Command Line Tool -> Clang

  2. 在 main.m 中写一个类,如下方代码:
    在 main.m 中自定义一个类

  3. 我们要看的是 [super description] 中的 super

  4. 打开 main.m 所在的位置

  5. 在终端输入cd main.m所在的位置

  6. $ clang -rewrite-objc main.m

  7. 如果出现下方图片中的错误
    在这里插入图片描述

  8. 修改错误:偏好设置 -> locations -> Command Line Tools -> Xcode 8 -> 再次运行终端命令 -> 成功

  9. 这时候,项目的文件夹中会有一个 main.cpp 文件.

  10. 打开 -> command + F 查找 -> @autoreleasepool -> 在这个属性的上面就是 我们自定义的 person 类 .
    如何查找自定义的类

  11. 从上面的代码可以看到,最终 自定义的类会变成结构体

  12. 把方法转换成函数
    OC中的方法
    static NSString * _I_Person_description 函数
    _I_Person_description 函数

  13. 把函数中的强转类型去掉

// 原函数
((NSString *(*)(__rw_objc_super *, SEL))(void *) objc_msgSendSuper)((__rw_objc_super){(id)self, (id)class_getSuperclass(objc_getClass("Person"))},sel_registerName("description"));

// 1. 第一次删除 (NSString *(*)(__rw_objc_super *, SEL))
objc_msgSendSuper((__rw_objc_super){(id)self, (id)class_getSuperclass(objc_getClass("Person"))},sel_registerName("description"));

// 2. 第二次删除 (__rw_objc_super)
objc_msgSendSuper({(id)self, (id)class_getSuperclass(objc_getClass("Person"))},sel_registerName("description"));

// 3. 第三次删除 删除 (id )
objc_msgSendSuper({self, class_getSuperclass(objc_getClass("Person"))},sel_registerName("description"));
  1. objc_msgSendSuper 函数的形参是什么?
    • struct objc_super *super, SEL op, …
    • 第一个参数传的是结构体,一个 objc_super 的结构体
    • objc_msgSendSuper的形参传什么
  2. objc_super 的代码
    objc_super 的代码
  • receiver : 消息发送者
  • # if !defined(__cplusplus) && !__OBJC2__
    • 如果不是 c++ 并且 不是 OC 代码的话,走 Class class
    • 如果是,走 Class super_class
  • 第一个形参是消息发送者,第二个形参是 sel_registerName("description")
  • 对应 ->
{self, class_getSuperclass(objc_getClass("Person"))},sel_registerName("description")

消息发送者, Class super_class
self =  消息发送者
class_getSuperclass(objc_getClass("Person")) =  Class super_class

调用的方法 = sel_registerName("description")
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值