寫在前面
經常在網上看到[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]
打印結果分別為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
調用本質的原理我們在這片文章就分析清楚了,如有錯誤請多多指教,最后歡迎大家去我的個人技術博客逛逛。