【iOS重學】一篇文章講清楚super

寫在前面

經常在網上看到[super xxx]這種輸出什么內容等類似的面試題,本文就主要來詳細剖析一下這種[super xxx]super調用的底層原理。

場景

博主這里用一個常看到的面試題來引出本文的主題:

// Person類
@interface Person : NSObject

@end
  
@implementation Person

@end

// Student類
@interface Student : Person

@end

@implementation Student

- (instancetype)init {
    if (self = [super init]) {
        [super class];
        NSLog(@"1 - %@",[self class]);
        NSLog(@"2 - %@",[super class]);
        NSLog(@"3 - %@",[self superclass]);
        NSLog(@"4 - %@",[super superclass]);
    }
    return self;
}

@end

打印結果如下:

2023-01-30 16:10:51.753257+0800 SuperDemo[27224:16387952] 1 - Student
2023-01-30 16:10:51.754489+0800 SuperDemo[27224:16387952] 2 - Student
2023-01-30 16:10:51.754682+0800 SuperDemo[27224:16387952] 3 - Person
2023-01-30 16:10:51.754821+0800 SuperDemo[27224:16387952] 4 - Person

結果分析:

[super class][self superclass]打印結果分別為StudentPerson毫無疑問。
可能大家比較好奇為什么[super class][super superclass] 的打印結果依然是StudentPerson

我們這里以[super class]為例來看其底層結構:
用命令xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc -fobjc-arc -fobjc-runtime=ios-10.0.0 Student.m將Student.m文件轉化為c++文件,[super class]底層如下:

((Class (*)(__rw_objc_super *, SEL))(void *)objc_msgSendSuper)((__rw_objc_super){(id)self, (id)class_getSuperclass(objc_getClass("Student"))}, sel_registerName("class"));

簡化之后為:

objc_msgSendSuper(__rw_objc_super{
            self,
            class_getSuperclass(objc_getClass("Student"))
},sel_registerName("class"));

為了讓大家更方便理解,最終結構如下:

struct __rw_objc_super arg = {
            self,
            class_getSuperclass(objc_getClass("Student"))
};
objc_msgSendSuper(arg,sel_registerName("class"));

在源碼中我們搜索一下objc_super結構體:

1.png

從上面的分析,我們可以看到:[super class]中消息接收者還是self也就是說還是Student,同理[super superclas]打印結果還是Person

寫在最后

關于super調用本質的原理我們在這片文章就分析清楚了,如有錯誤請多多指教,最后歡迎大家去我的個人技術博客逛逛。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容