runtime各种数据结构
对象
struct objc_object {
private:
isa_t isa;
public:
// ISA() assumes this is NOT a tagged pointer object
Class ISA();
// getIsa() allows this to be a tagged pointer object
Class getIsa();
...
}
所以说,只要是oc对象就有isa
指针,但是这句话也不完全对
并不是所有的oc对象都有isa指针,例如Tagged Pointer对象没有isa指针,具体可以看这个文章深入理解Tagged Pointer
isa
指针是指向一个类对象,为啥说的类对象,我们接着看类的数据结构
类
struct objc_class : objc_object {
// Class ISA;
Class superclass;
...
}
类的结构体也是继承对象的,所以说类也是一个对象
这里理解可以看下
元类的文章,理解下元类,实例对象,类对象,元类对象
协议
struct protocol_t : objc_object {
const char *mangledName;
// 这个协议遵循的协议
// 比如我们定义协议一般会xxDelete<NSObject>
struct protocol_list_t *protocols;
// 下面几个看命名就知道什么意思了
method_list_t *instanceMethods;
method_list_t *classMethods;
method_list_t *optionalInstanceMethods;
method_list_t *optionalClassMethods;
property_list_t *instanceProperties;
...
}
1.协议的结构体也是继承objc_object
,说明协议也是对象
2.mangledName
是源于c++
的命名重整技术,可以这样简单理解,c++
之所以可以方法重载是基于命名重整这个技术
print(int i)
print(char c)
这个技术简单理解,就是编译器,在底层重新给方法命名,比如上面的print,在底层可能会生成i_print
和c_print
分类
struct category_t {
// 所属的类名,而不是Category的名字
const char *name;
// 所属的类,这个类型是编译期的类,这时候类还没有被重映射
classref_t cls;
// 实例方法列表
struct method_list_t *instanceMethods;
// 类方法列表
struct method_list_t *classMethods;
// 协议列表
struct protocol_list_t *protocols;
// 实例属性列表
struct property_list_t *instanceProperties;
// Fields below this point are not always present on disk.
// 类属性列表
struct property_list_t *_classProperties;
method_list_t *methodsForMeta(bool isMeta) {
if (isMeta) return classMethods;
else return instanceMethods;
}
property_list_t *propertiesForMeta(bool isMeta, struct header_info *hi);
};
因为没有成员变量列表,所以分类不可以添加成员变量,但是因为有属性列表,所以可以添加属性
我们这里还发现了一个类属性列表_classProperties
,
这个的用法是
@property (class, nonatomic, copy) NSUUID *identifier;
如果这样声明,xcode不会自动生成set和get方法,你得自己实现,而且你实现的get和set方法是类方法哦
这个是为了跟swift
交互诞生的
属性
struct property_t {
const char *name;
const char *attributes;
};
// 测试代码
@property (nonatomic, copy) NSString *string;
objc_property_t t = class_getProperty([self class],"string");
const char *name = property_getName(t);
const char *att = property_getAttributes(t);
NSLog(@"name:%s,att:%s",name, att);
// 输出
name:string,att:T@"NSString",C,N,V_string
T代表类型@"NSString" 参考Type Encodings
C代表copy
N代表nonatomic
V代表实例变量_string
方法
struct method_t {
// 方法编号
SEL name;
// 参数和返回类型encode
const char *types;
// 函数指针
IMP imp;
// 根据方法名进行方法排序(这个我也搞不懂用途)
struct SortBySELAddress :
public std::binary_function<const method_t&,
const method_t&, bool>
{
bool operator() (const method_t& lhs,
const method_t& rhs)
{ return lhs.name < rhs.name; }
};
};
成员变量
struct ivar_t {
int32_t *offset; // 偏移
const char *name; // 名字
const char *type; // 类型
// alignment is sometimes -1; use alignment() instead
uint32_t alignment_raw; // 对齐
uint32_t size; // 大小
uint32_t alignment() const {
if (alignment_raw == ~(uint32_t)0) return 1U << WORD_SHIFT;
return 1 << alignment_raw;
}
};