iOS面试题/2019

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 方法中会负责初始化内存区域,还可以在根类或者父类中,添加一些必要的属性

上一篇 下一篇

猜你喜欢

热点阅读