self、 superclass 穷遂、 super的區(qū)別
self函匕、 superclass 、 super
self : 當前方法的調用者
class:獲取方法調用者的類對象
superclass:獲取方法調用者的父類對象
super:不是一個指針,編譯指示器(標識符)蚪黑,在程序編譯時內部會做一些特殊處理
super的本質:其實還是當前對象去調用,只不過讓當前對象去調用父類方法盅惜, super不是父類對象,指的是父類方法。
驗證:
在一個main.m文件中定義一個Person類祠锣,重寫description方法酷窥。
#import <objc/message.h>
@interface Person : NSObject
@end
@implementation Person
- (NSString *)description
{
? ? // super:當前對象調用
? ? // 調用NSObject方法
? return [super description];
}
@end
int main(int argc, const char * argv[]) {
? ? @autoreleasepool {
? ? }
? ? return 0;
}
在終端使用cd命令跳轉的main.m所在的目錄下,然后輸入:clang -rewrite-objc main.m 命令伴网,便可以將main.m文件轉換為mian.cpp文件蓬推,打開文件在文件的末尾出可以看到[super description]這句代碼的底層實現(xiàn)如下:
((NSString *(*)(__rw_objc_super *, SEL))(void *)objc_msgSendSuper)((__rw_objc_super){(id)self, (id)class_getSuperclass(objc_getClass("Person"))}, sel_registerName("description"));
將上面代碼簡化掉強制類型轉換后代碼如下:
objc_msgSendSuper({self, class_getSuperclass(objc_getClass("Person"))}, sel_registerName("description"))
其中{self,class_getSuperclass(objc_getClass("Person"))}j即為super的底層實現(xiàn),所以使用super調用父類的方法澡腾,其本質仍是當前對象調用父類的方法沸伏。
// ViewController.m文件
- (void)viewDidLoad {
? ? // 創(chuàng)建SubPerson
? ? SubPerson *subP = [[SubPerson alloc] init];
? ? [subP test];
}
//Person.m 文件
- (void)test
{
? ? NSLog(@"%@ %@ %@ %@",[self class], [self superclass], [super class], [super superclass]);
}
//SubPerson.m 文件
- (void)test
{
? ? // 測試1
? ? NSLog(@"%@ %@ %@ %@",[self class], [self superclass], [super class], [super superclass]);
? ? // 測試2
? ? [super test];
}
測試1打印結果為:SubPerson Person SubPerson Person
測試2打印結果為:SubPerson Person SubPerson Person