isa指针图解
1653926-62a8c73af51e4446.png代码例子佐证 - 实例对象isa验证
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
// MJPerson
@interface CSPerson : NSObject {
@public
int _age;
}
@property (nonatomic, assign) int no;
- (void)personInstanceMethod;
+ (void)personClassMethod;
@end
@implementation CSPerson
- (void)test {
}
- (void)personInstanceMethod {
}
+ (void)personClassMethod {
}
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
// CSPerson类对象的地址:0x0000000100001240
// CSPerson实例对象的isa:0x001d800100001241
// isa(0x001d800100001241) & ISA_MASK(0x0000000ffffffff8):0x0000000100001240
CSPerson *person = [[CSPerson alloc] init];
Class personClass = [CSPerson class];
Class personMetaClass = object_getClass(personClass);
NSLog(@"%p %p %p", person, personClass, personMetaClass);
}
return 0;
}
打印结果
1653926-ac1d7ff4d011e1b9.png从打印结果我们可以知道实例对象的isa指针 & ISA_MASK等于类对象的地址
代码例子佐证 - 类对象isa验证
CSPerson代码还是使用上述代码,只是增加一个结构体
struct cs_objc_class {
Class isa;
};
int main(int argc, const char * argv[]) {
@autoreleasepool {
// CSPerson类对象的地址:0x001d800100001219
// CSPerson元类对象的地址: 0x0000000100001218
// isa(0x001d800100001219) & ISA_MASK(0x0000000ffffffff8) = 0x0000000100001218
Class personClass = [CSPerson class];
struct cs_objc_class *personClass2 = (__bridge struct cs_objc_class *)(personClass);
Class personMetaClass = object_getClass(personClass);
NSLog(@"%p %p %p", person, personClass, personMetaClass);
}
return 0;
}
输出结果
1653926-f83d1ced16bf5d38.png从打印结果我们可以知道类对象的isa指针 & ISA_MASK等于元类对象的地址
superclass
代码例子佐证 - 新增CSStudent类,cs_objc_class结构体
// CSStudent
@interface CSStudent : CSPerson {
@public
int _weight;
}
@property (nonatomic, assign) int height;
- (void)studentInstanceMethod;
+ (void)studentClassMethod;
@end
@implementation CSStudent
- (void)test{
}
- (void)studentInstanceMethod{
}
+ (void)studentClassMethod{
}
@end
struct cs_objc_class {
Class isa;
Class superclass;
};
int main(int argc, const char * argv[]) {
@autoreleasepool {
// 3\. superclass
struct cs_objc_class *personClass = (__bridge struct cs_objc_class *)([CSPerson class]);
struct cs_objc_class *studentClass = (__bridge struct cs_objc_class *)([CSStudent class]);
NSLog(@"%p %p", personClass, studentClass);
}
return 0;
}
运行结果
1653926-852553024882f13f.png从打印结果可知,类对象的superclass指向元类对象地址
项目连接地址 - Isa-class-detail
struct objc_class
1653926-4b79e8aa021f509c.png- class、meta-class对象的本质结构都是struct objc_class
窥探struct objc_class的结构
1653926-6ff583180e68579d.png代码佐证
引入#import "MJClassInfo.h"文件,然后编写类
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
#import "MJClassInfo.h"
// CSPerson
@interface CSPerson : NSObject {
@public
int _age;
}
@property (nonatomic, assign) int no;
- (void)personInstanceMethod;
+ (void)personClassMethod;
@end
@implementation CSPerson
- (void)test {
}
- (void)personInstanceMethod {
}
+ (void)personClassMethod {
}
@end
// CSStudent
@interface CSStudent : CSPerson {
@public
int _weight;
}
@property (nonatomic, assign) int height;
- (void)studentInstanceMethod;
+ (void)studentClassMethod;
@end
@implementation CSStudent
- (void)test{
}
- (void)studentInstanceMethod{
}
+ (void)studentClassMethod{
}
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
CSStudent *stu = [[CSStudent alloc] init];
stu->_weight = 10;
mj_objc_class *studentClass = (__bridge mj_objc_class *)([CSStudent class]);
mj_objc_class *personClass = (__bridge mj_objc_class *)([CSStudent class]);
class_rw_t *studentClassData = studentClass->data();
class_rw_t *personClassData = personClass->data();
class_rw_t *studentMetaClassData = studentClass->metaClass()->data();
class_rw_t *personMetaClassData = personClass->metaClass()->data();
NSLog(@"1111");
}
return 0;
}
运行结果分析
mj_objc_class结构
- 类对象
mj_objc_class结构
- 元类对象
mj_objc_class结构
面试题
1.对象的isa指针指向哪里?
- instance对象的isa指向class对象
- class对象的isa指向meta-class对象
- meta-class对象的isa指向基类的meta-class对象
2.OC的类信息存放在哪里?
- 对象方法、属性、成员变量、协议信息,存放在class对象中
- 类方法,存放在meta-class对象中
- 成员变量的具体值,存放在instance对象
本文参考:
路飞_Luck (https://www.jianshu.com/p/07f7b96bb03f)
以及借鉴MJ的教程视频
非常感谢.
网友评论