[self class]和[super class]
2021-03-30 本文已影响0人
磊Se
问题
Teacher
继承Person
,Person
继承NSObject
,super
与self
调用class
方法打印结果
@implementation Teacher
- (instancetype)init
{
self = [super init];
if (self) {
//猜测 Teacher
NSLog(@"[self class]:%@",[self class]);
//猜测 Person
NSLog(@"[self superclass]:%@",[self superclass]);
//猜测 Person
NSLog(@"[super class]:%@",[super class]);
//猜测 NSObject
NSLog(@"[super superclass]:%@",[super superclass]);
}
return self;
}
实际打印结果
2021-03-30 13:51:23.283653+0800 InterViewTest[6675:102791] [self class]:Teacher
2021-03-30 13:51:23.283698+0800 InterViewTest[6675:102791] [self superclass]:Person
2021-03-30 13:51:23.283736+0800 InterViewTest[6675:102791] [super class]:Teacher
2021-03-30 13:51:23.283773+0800 InterViewTest[6675:102791] [super superclass]:Person
[super class]
猜测与我们相差甚远,下面进行分析
[self class]
[self class]
实际是调用objc_msgSend()
objc_msgSend(id _Nullable self, SEL _Nonnull op, ...)
self
即消息接收者,SEL
则是class
方法的选择器
- (Class)class {
return object_getClass(self);
}
/***********************************************************************
* object_getClass.
* Locking: None. If you add locking, tell gdb (rdar://7516456).
**********************************************************************/
Class object_getClass(id obj)
{
if (obj) return obj->getIsa();
else return Nil;
}
class
方法则返回self
的isa
,则[self class]
原理就解释清楚了
[super class]
[super class]
实际是调用objc_msgSendSuper()
objc_msgSendSuper(struct objc_super * _Nonnull super, SEL _Nonnull op, ...)
super
是一个关键字,它的本质是objc_super
结构体
struct objc_super {
/// Specifies an instance of a class.
__unsafe_unretained _Nonnull id receiver;// 消息接收者
/// Specifies the particular superclass of the instance to message.
#if !defined(__cplusplus) && !__OBJC2__
/* For compatibility with old objc-runtime.h header */
__unsafe_unretained _Nonnull Class class;
#else
__unsafe_unretained _Nonnull Class super_class;
#endif
// super_class 是第一个要搜索的类
/* super_class is the first class to search */
};
- 消息接收者
receiver-->self
即Teacher
对象 - 方法查找时,搜索的第一个类是
super_class
- 相当于
Teacher
对象(reveiver->self
)调用objc_msgSend
方法,但是从Person
类开始查找class
方法
总结:
-
[self class]
实际是调用objc_msgSend()
-
[self class]
class
方法从Teacher
类中开始查找 -
[super class]
实际是调用objc_msgSendSuper()
-
[super class]
class
方法从Person
类中开始查找 - 实际
[self class]
和[super class]
消息接收者相同,都是self(Teacher)
-
Teacher
和Person
中class
方法实现相同,所以结果相同