/*
[super message]的底层实现
1.消息接收者仍然是子类对象
2.从父类开始查找方法的实现
*/
struct objc_super {
__unsafe_unretained _Nonnull id receiver; // 消息接收者
__unsafe_unretained _Nonnull Class super_class; // 消息接收者的父类
};
- (void)run
{
// super调用的receiver仍然是MJStudent对象
[super run];
// struct objc_super arg = {self, [MJPerson class]};
//
// objc_msgSendSuper(arg, @selector(run));
//
//
// NSLog(@"MJStudet.......");
}
- (instancetype)init
{
if (self = [super init]) {
NSLog(@"[self class] = %@", [self class]); // MJStudent
NSLog(@"[self superclass] = %@", [self superclass]); // MJPerson
NSLog(@"--------------------------------");
// objc_msgSendSuper({self, [MJPerson class]}, @selector(class));
NSLog(@"[super class] = %@", [super class]); // MJStudent
NSLog(@"[super superclass] = %@", [super superclass]); // MJPerson
}
return self;
}
@end
class superclass 方法的底层实现
//@implementation NSObject
//
//- (Class)class
//{
// return object_getClass(self);
//}
//
//- (Class)superclass
//{
// return class_getSuperclass(object_getClass(self));
//}
//
//@end
// NSLog(@"%d", [[NSObject class] isKindOfClass:[NSObject class]]);//1
// NSLog(@"%d", [[NSObject class] isMemberOfClass:[NSObject class]]);//0
// NSLog(@"%d", [[MJPerson class] isKindOfClass:[MJPerson class]]);//0
// NSLog(@"%d", [[MJPerson class] isMemberOfClass:[MJPerson class]]);//0
// 这句代码的方法调用者不管是哪个类(只要是NSObject体系下的),都返回YES
NSLog(@"%d", [NSObject isKindOfClass:[NSObject class]]); // 1
NSLog(@"%d", [NSObject isMemberOfClass:[NSObject class]]); // 0
NSLog(@"%d", [MJPerson isKindOfClass:[MJPerson class]]); // 0
NSLog(@"%d", [MJPerson isMemberOfClass:[MJPerson class]]); // 0
// id person = [[MJPerson alloc] init];
// NSLog(@"%d", [person isMemberOfClass:[MJPerson class]]);//1
// NSLog(@"%d", [person isMemberOfClass:[NSObject class]]);//0
// NSLog(@"%d", [person isKindOfClass:[MJPerson class]]);//1
// NSLog(@"%d", [person isKindOfClass:[NSObject class]]);//1
// NSLog(@"%d", [MJPerson isMemberOfClass:object_getClass([MJPerson class])]);//1
// NSLog(@"%d", [MJPerson isKindOfClass:object_getClass([NSObject class])]);//1
// NSLog(@"%d", [MJPerson isKindOfClass:[NSObject class]]);//1 因为 最后调用的是 元类 NSObject的superclass 的时候 指向的是 NSObject 的class 对象,最后获取到的是 [NSObject class] 对象,正好等于参数[NSObject class]
NSObject 底层 实现
- (BOOL)isMemberOfClass:(Class)cls {
return [self class] == cls;
}
- (BOOL)isKindOfClass:(Class)cls {
for (Class tcls = [self class]; tcls; tcls = tcls->superclass) {
if (tcls == cls) return YES;
}
return NO;
}
+ (BOOL)isMemberOfClass:(Class)cls {
return object_getClass((id)self) == cls;
}
+ (BOOL)isKindOfClass:(Class)cls {
for (Class tcls = object_getClass((id)self); tcls; tcls = tcls->superclass) {
if (tcls == cls) return YES;
}
return NO;
}
NSObject *obj2 = [[NSObject alloc]init];
id cls = [MJPerson class];
void *obj = &cls;
[(__bridge id)obj print];
/*
1.print为什么能够调用成功?
2.为什么self.name变成了ViewController等其他内容
*/
内存结构
image.png
image.png image.png
相当于 _name 的预期地址和 obj2 的地址 重合了
网友评论