isa指针

本文详细探讨了OC中对象的isa指针,包括instance、class和meta-class的isa指向,以及superclass的层级关系。同时阐述了对象方法和类方法的调用轨迹,是iOS底层原理学习的笔记。

OC的类信息存放在哪里?

在这里插入图片描述

instance对象

isa、成员变量的具体值

class对象

isa、superclass、对象方法、属性、成员变量(名字、类型等信息)、协议信息

meta-class对象

isa、superclass、类方法
//	结构体继承(c++的结构体 和 类 基本没有区别;成员变量的作用域有一定的区别)
struct objc_class : objc_object {
    // Class ISA;
    Class superclass;
    cache_t cache;				//	方法缓存 
    class_data_bits_t bits;		//	用于获取具体的类信息 & FAST_DATA_MASK
	
	class_rw_t *data() { 
        return bits.data();
    }
}
struct objc_object {
    isa_t isa;
}

class_rw_t* data() {
        return (class_rw_t *)(bits & FAST_DATA_MASK);
}

struct class_rw_t {
    uint32_t flags;
    uint32_t version;
    uint16_t witness;
    const class_ro_t *ro;
    method_array_t methods;			//	方法列表
    property_array_t properties;	//	属性列表
    protocol_array_t protocols;		//	协议列表
    Class firstSubclass;
    Class nextSiblingClass;
    char *demangledName;
}

struct class_ro_t {
    uint32_t flags;
    uint32_t instanceStart;
    uint32_t instanceSize;			//	instance对象占用的内存空间
#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;
}

对象的isa指针指向哪里?

在这里插入图片描述

指针指向:

一、isa

1、instance的isa指向class
2、class的isa指向meta-class
3、meta-class的isa指向基类的meta-class

二、superclass

1、class的superclass指向父类的class(如果没有父类,superclass指向nil)
2、meta-class的superclass指向父类的meta-class(基类的meta-class的superclass指向基类的class)

方法调用轨迹:

一、instance调用对象方法的轨迹

isa找到class,如方法不存在,就通过superclass找父类

二、class调用类方法的轨迹

isa找到meta-class,如方法不存在,就通过superclass找父类
@interface TBPerson : NSObject

@end

@implementation TBPerson

@end
//	继承自TBPerson
@interface TBStudent : TBPerson

@end

@implementation TBStudent

@end

struct tb_objc_object {
    Class isa;
    Class superclass;
};

TBPerson *person = [[TBPerson alloc] init];
//  person的类对象
Class person_class = object_getClass(person);
//  class里面有isa但是并不暴露出来,我们需要自己进行转换
struct tb_objc_object *person_class1 = (__bridge struct tb_objc_object *)(person_class);
//  person的元类对象
Class meta_class = object_getClass(person_class);
//	studdent的class对象
struct tb_objc_object *student_class = (__bridge struct tb_objc_object *)([TBStudent class]);
/*
	地址打印
	从64bit开始,isa需要进行一次位运算(&ISA_MASK),才能计算出真实地址
	由于运行环境为Mac命令行 __x86_64__
*/	
//	instance对象的isa和class
(lldb) p/x person_class
(Class) $0 = 0x0000000100002110 
(lldb) p/x person->isa
(Class) $1 = 0x001d800100002111
(lldb) p/x 0x001d800100002111 & 0x00007ffffffffff8
(long) $2 = 0x0000000100002110
//	class对象的isa和meta_class
(lldb) p/x person_class1->isa
(Class) $0 = 0x00000001000020e8
(lldb) p/x meta_class
(Class) $1 = 0x00000001000020e8
(lldb) p/x 0x00000001000020e8 & 0x00007ffffffffff8
(long) $2 = 0x00000001000020e8
/*
	由以上打印可以看出,instance对象的isa 保存的值,并不是class对象的地址(isa并不是直接指向)
	需要进行一次位运算&ISA_MASK
*/
# if __arm64__
#   define ISA_MASK        0x0000000ffffffff8ULL
# elif __x86_64__
#   define ISA_MASK        0x00007ffffffffff8ULL
# endif

//	superclass是不需要进行计算的,直接保存着父类的地址
(lldb) p/x person_class1
(tb_objc_object *) $0 = 0x00000001000021a8
(lldb) p/x student_class->superclass
(Class) $1 = 0x00000001000021a8 

PS 此文为学习 李明杰 老师的 iOS底层原理课程所写笔记
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值