iOS self 与 super
2019-05-26 本文已影响140人
7890陈
下面是一道面试题
// .h文件
@interface Son : Father
// .m 文件
- (instancetype)init
{
self = [super init];
if (self) {
NSLog(@"%@",NSStringFromClass([self class]));
NSLog(@"%@",NSStringFromClass([super class]));
}
return self;
}
问运行程序,打印的结果是什么?
class 方法
+ (Class)class
{
return object_getClass(self);
}
clang 一下 Son.m 文件
可以看出来 self 调用时,使用的是 objc_msgSend,self 是在当前类中查找方法
super 调用时,使用的是 objc_msgSendSuper,super只是编译指示符,在父类查找方法,调用的主体还是 self
// objc_msgSend
objc_msgSend(void /* id self, SEL op, ... */ )
// objc_msgSuperSend
objc_msgSendSuper(struct objc_super * _Nonnull super, SEL _Nonnull op, ...)
// objc_super 结构体
#ifndef OBJC_SUPER
#define OBJC_SUPER
/// Specifies the superclass of an instance.
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 */
};
#endif
这个 receiver 就是 Son 的对象,super_class 是 Father,class是 Son
所以答案是 Son Son
super是编译器的特殊字符,并不是父类的对象,父类对象可以通过 superclass 得到
题外:
- (instancetype)init
{
self = [super init];
if (self) {
}
return self;
}
self = [self init];会调用父类的 init 方法 ,直到根类( NSObject) 中的 init 方法,在根类的 init 方法中会负责初始化内存区域,还可以在根类或者父类中,添加一些必要的属性