类的结构
typedef struct objc_class *Class;
typedef struct objc_object *id;
struct objc_object {
private:
isa_t isa;
public:
//...很多方法
}
struct objc_class : objc_object {
//Clas isa;
Class superclass;
cache_t cache;
class_data_bits_t bits;
class_rw_t *data() {
return bits.data();
}
void setData(class_rw_t *newData) {
bits.setData(newData);
}
//…省略很多方法
}
Class对象的结构体内除了有继承自objc_object
的Class isa;
,还看到了熟悉的superclass
。宁外还有cache_t cache;
以及class_data_bits_t bits;
这些重要的成员。
-
cache_t cache;
占用16个字节的内存空间
struct cache_t {
explicit_atomic<struct bucket_t *> _buckets;
explicit_atomic<mask_t> _mask;
#if __LP64__
uint16_t _flags;
#endif
uint16_t _occupied;
-
class_data_bits_t bits;
占8个字节内存空间
struct class_data_bits_t {
uintptr_t bits;
//...
}
class_rw_t *data() {
return bits.data();
}
可以获取到bits数据
验证一下类的内存结构和信息的存放
@interface MyClass : NSObject{
NSString *myName;
}
@property(nonatomic,copy)NSString *youName;
- (void)say;
+ (void)hello;
@end
@implementation MyClass
- (void)say{
NSLog(@"say");
}
+ (void)hello{
NSLog(@"hello");
}
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
MyClass *myClass = [[MyClass alloc]init];
NSLog(@"");
}
return 0;
}
myClass内存指针.jpg
按照类的结构体定义来看 前8个字节存放的是isa
指向的应该是myClass
这个实例对象的类对象MyClass
我们验证一下(0x00007ffffffffff8ULL
是模拟器环境下的ISA_MASK
对应的值):
那么 接下来就要看看MyClass
这个类对象内部存储:
注意上图中
$6
是MyClass
而$6
的isa
还是MyClass
但是他们的指针地址已经不一样,因为类对象MyClass
的isa
指向的是元类MyClass
。那么 按照苹果给出的isa
指向图 元类的isa
指向的是根元类这里可以验证一下验证玩了对象的isa
指向 现在来看看类的内存结构:
MyClass
的前8个字节是isa
,再往后8个字节就是superclass
再往后的16个字节就是cache
,最后才是存放了类相关方法、属性等信息的bits
。如下图所示
通过调用
bits->data()
可以返回一个class_rw_t *
结构体指针来解读一下这个结构体里面的内容:
class_rw_t
上图中的class_rw_t
就是存放类的各种协议、属性、方法等的位置。
具体如何获取请看源码简示:
struct class_rw_t {
uint32_t flags;
uint16_t witness;
#if SUPPORT_INDEXED_ISA
uint16_t index;
#endif
explicit_atomic<uintptr_t> ro_or_rw_ext;
Class firstSubclass;
Class nextSiblingClass;
const method_array_t methods() const {
//...方法
}
const property_array_t properties() const {
//...属性
}
const protocol_array_t protocols() const {
//...协议
}
//...
}
简单查看一下属性:
注意 成员变量在这里不能获取到而是通过ro()
来获取class_ro_t *
来获取:
struct class_ro_t {
uint32_t flags;
uint32_t instanceStart;
uint32_t instanceSize;
#ifdef __LP64__
uint32_t reserved;
#endif
const uint8_t * ivarLayout;
const char * name;
method_list_t * baseMethodList;
protocol_list_t * baseProtocols;
const ivar_list_t * ivars;
const uint8_t * weakIvarLayout;
property_list_t *baseProperties;
method_list_t *baseMethods() const {
return baseMethodList;
}
//...
};
这一节先写这么多
网友评论