- isa的调用
- class的superclass
- meta-class的superclass
- 总结1
- 总结2
- isa细节
- class和meta-class的结构(视频28,未解答)
- 面试题解答
1、isa的调用

实例对象方法调用过程 (instance)
- instance的isa指向class
- 当调用对象方法时,通过instance的isa找到class,最后找到对象方法的实现进行调用

类对象方法调用过程
- class的isa指向meta-class
- 当调用类方法时,通过class的isa找到meta-class,最后找到类方法的实现进行调用

2、class的superclass

- 子类调用父类方法
@interface MJPerson : NSObject <NSCopying>
{
@public
int _age;
}
@property (nonatomic, assign) int no;
- (void)personInstanceMethod;
+ (void)personClassMethod;
@end
@implementation MJPerson
- (void)personInstanceMethod {
}
+ (void)personClassMethod {
}
- (id)copyWithZone:(NSZone *)zone {
return nil;
}
@end
@interface MJStudent : MJPerson <NSCopying>
{
@public
int _weight;
}
@property (nonatomic, assign) int height;
@end
@implementation MJStudent
- (void)studentInstanceMethod {
}
+ (void)studentClassMethod {
}
- (id)initWithCoder:(NSCoder *)aDecoder {
return nil;
}
@end
MJStudent *student = [[MJStudent alloc] init];
[student personInstanceMethod];

3、meta-class的superclass

当Student的class要调用Person的类方法时,会先通过isa找到Student的meta-class,然后通过superclass找到Person的meta-class,最后找到类方法的实现进行调用
4、总结1

- instance的isa指向class
- class的isa指向meta-class
- meta-class的isa指向基类的meta-class
- class的superclass指向父级的class(如果没有父类,superclass指针为nil)
- meta-class的superclass指向父类的meta-class(基类的meta-class的superclass指向基类的class)
- instance调用对象的轨迹
- 如果基类也不存在,报经典崩溃问题(方法找不到)
- isa找到class,方法不存在,就通过superclass找父类

- 类方法调用轨迹
isa找到meta-class,方法不存在,就通过superclass找父类

5、总结2
案例1、
@implementation NSObject (Test)
+ (void)test {
NSLog(@"[NSObject test]----%p", self);
}
@end
@interface MJPerson : NSObject
+ (void)test;
@end
@implementation MJPerson
+ (void)test {
NSLog(@"[MJPerson test]----%p", self);
}
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSLog(@"[MJPerson test]----%p", [MJPerson class]);
NSLog(@"[NSObject test]----%p", [NSObject class]);
[MJPerson test];
[NSObject test];
}
return 0;
}
2019-06-09 20:24:39.262084+0800 test[4058:646500] [MJPerson test]----0x1000011e0
2019-06-09 20:24:39.262389+0800 test[4058:646500] [NSObject test]----0x7fffa423f140
2019-06-09 20:24:39.262415+0800 test[4058:646500] [MJPerson test]----0x1000011e0
2019-06-09 20:24:39.262433+0800 test[4058:646500] [NSObject test]----0x7fffa423f140
如果类中只存在对象方法,但是却用类方法调用,会有什么后果呢?
@implementation NSObject (Test)
- (void)test {
NSLog(@"-[NSObject test]----%p", self);
}
@end
@interface MJPerson : NSObject
@end
@implementation MJPerson
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSLog(@"[MJPerson test]----%p", [MJPerson class]);
NSLog(@"[NSObject test]----%p", [NSObject class]);
[MJPerson test];
[NSObject test];
}
return 0;
}
2019-06-09 20:26:51.564113+0800 test[4095:651682] [MJPerson test]----0x1000011e0
2019-06-09 20:26:51.564447+0800 test[4095:651682] [NSObject test]----0x7fffa423f140
2019-06-09 20:26:51.564471+0800 test[4095:651682] -[NSObject test]----0x1000011e0
2019-06-09 20:26:51.564489+0800 test[4095:651682] -[NSObject test]----0x7fffa423f140

6、isa细节
-
从64bit开始,isa需要进行一次位运算,才能计算出真实地址(需要&ISA_MASK)
5E8FRDO920_54_18__06_09_2019.jpg
7、面试题解答
对象的isa指针指向哪里?(经典图可以解答)
OC的类信息存放在哪里?
1、对象的isa指针指向哪里?(经典图可以解答)
- instance对象的isa指针指向class对象
- class对象的isa指向meta-class
- meta-class对象的isa指向基类的meta-class对象
2、OC的类信息存放在哪里?
- 对象方法、属性、成员变量、协议信息,存放在class对象中
- 类方法,存放在meta-class对象中
- 成员变量的具体值,存放在instance对象
网友评论