寫(xiě)在前面
經(jīng)常在網(wǎng)上看到[super xxx]這種輸出什么內(nèi)容等類似的面試題,本文就主要來(lái)詳細(xì)剖析一下這種[super xxx]中super調(diào)用的底層原理。
場(chǎng)景
博主這里用一個(gè)??吹降拿嬖囶}來(lái)引出本文的主題:
// 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
打印結(jié)果如下:
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
結(jié)果分析:
[super class]和[self superclass]打印結(jié)果分別為Student和Person毫無(wú)疑問(wèn)。
可能大家比較好奇為什么[super class]和[super superclass]的打印結(jié)果依然是Student和Person。
我們這里以[super class]為例來(lái)看其底層結(jié)構(gòu):
用命令xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc -fobjc-arc -fobjc-runtime=ios-10.0.0 Student.m將Student.m文件轉(zhuǎn)化為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"));
簡(jiǎn)化之后為:
objc_msgSendSuper(__rw_objc_super{
self,
class_getSuperclass(objc_getClass("Student"))
},sel_registerName("class"));
為了讓大家更方便理解,最終結(jié)構(gòu)如下:
struct __rw_objc_super arg = {
self,
class_getSuperclass(objc_getClass("Student"))
};
objc_msgSendSuper(arg,sel_registerName("class"));
在源碼中我們搜索一下objc_super結(jié)構(gòu)體:

1.png
從上面的分析,我們可以看到:
[super class]中消息接收者還是self也就是說(shuō)還是Student,同理[super superclas]打印結(jié)果還是Person。
寫(xiě)在最后
關(guān)于super調(diào)用本質(zhì)的原理我們?cè)谶@片文章就分析清楚了,如有錯(cuò)誤請(qǐng)多多指教,最后歡迎大家去我的個(gè)人技術(shù)博客逛逛。