创建一个 Father 类,再创建一个继承与 Father 的 Son 类。在 Son 中声明一个 exercise
方法打印 [self class]
和[super class]
Father 类
//Father.h
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface Father : NSObject
@end
NS_ASSUME_NONNULL_END
//Father.m
#import "Father.h"
@implementation Father
@end
Son 类
//Son.h
#import "Father.h"
NS_ASSUME_NONNULL_BEGIN
@interface Son : Father
- (void)exercise;
@end
NS_ASSUME_NONNULL_END
//Son.m
#import "Son.h"
@implementation Son
- (void)exercise
{
NSLog(@"\nself: %@\nsuper: %@",[self class],[super class]);
}
@end
创建 Son 对象,并调用方法 exercise
Son *son = [[Son alloc] init];
[son exercise];
打印结果
self: Son
super: Son
从结果来看可以发现在子类中打印 [self class]
与 [super class]
结果是相同的,都是打印调用者的 class
名称 Son
我们都知道 self
是类的隐藏参数,指向调用方法的这个类的实例,是一个 指针。
而 super
跟 self
不一样,并不是指向父类的指针,只是一个 编译器修饰符 作用。
用 self
调用方法是从该类的方法列表当中找对应方法调用,如果没有就从父类当中找;而 super
关键词是从父类的方法列表当中找,调用父类的那个方法。但是这两种方式的事件调用者都是当前的实例 Son ,最终都是找到了 NSObject 中的 class
的方法。
从 runtime
的底层API来看调用 [self class]
的时候是调用了
objc_msgSend(self,@selector(class))
直接从当前实例里找class的实现。
调用 [super class]
的时候是调用了
objc_msgSendSuper(<#struct objc_super *super#>, <#SEL op, ...#>)
里面传两个参数,第一个参数objc_super结构体中有两个成员:
receiver
: a pointer of typeid
. Specifies an instance of a class.super_class
: a pointer to aClass
data structure. Specifies the particular superclass of the instance to the message.
receiver
就是调用这个事件的接受者 self
,然后第二个就是父类的 class
Father,然后从这个 Father 类开始找 class
方法,一直找到了 NSObject ,最后这两个方法都是调用了 [self class]
打印当前类的 class
。
网友评论