寫在前面
經(jīng)常在網(wǎng)上看到[super xxx]這種輸出什么內(nèi)容等類似的面試題,本文就主要來詳細剖析一下這種[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]打印結果分別為Student和Person毫無疑問。
可能大家比較好奇為什么[super class]和[super superclass]的打印結果依然是Student和Person。
我們這里以[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調用本質的原理我們在這片文章就分析清楚了,如有錯誤請多多指教,最后歡迎大家去我的個人技術博客逛逛。