iOS runtime之元素认知(一)

tech2023-05-25  102

一、什么是runtime

简而言之,Objective-C Runtime是一个将C语言转化为面向对象语言的扩展。 我们将C++和Objective进行对比,虽然C++和Objective-C都是在C的基础上加入面向对象的特性扩充而成的程序设计语言,但二者实现的机制差异很大。C++是基于静态类型,而Objective-C是基于动态运行时类型。也就是说用C++编写的程序编译时就直接编译成了可令机器读懂的机器语言;用Objective-C编写的程序不能直接编译成可令机器读懂的机器语言,而是在程序运行的时候,通过Runtime把程序转为可令机器读懂的机器语言。Runtime是Objective不可缺少的重要一部分。

Runtime其实有两个版本: “modern” 和 “legacy”。我们现在用的 Objective-C 2.0 采用的是现行 (Modern) 版的 Runtime 系统,只能运行在 iOS 和 macOS 10.5 之后的 64 位程序中。而 macOS 较老的32位程序仍采用 Objective-C 1 中的(早期)Legacy 版本的 Runtime 系统。这两个版本最大的区别在于当你更改一个类的实例变量的布局时,在早期版本中你需要重新编译它的子类,而现行版就不需要。

runtime是一个c和汇编写的动态库,它就像一个小小的系统,将OC和C紧密关联,这个系统主要做两件事 :

1、封装C语言的结构体和函数,让开发者在运行时创建、检查或者修改类、对象和方法等等。2、传递消息,找出方法的最终执行代码。 1、无参数

OC定义方法

[receiver message]

runtime转化C语言的代码:

objc_msgSend(receiver, selector) 2、有参数

OC定义方法

[receiver message:arg1 ...]

runtime转化C语言的代码:

objc_msgSend(receiver, selector, arg1, arg2, ...) 3、多方法

OC定义方法

NSObject *object = [[NSObject alloc] init];

runtime转化C语言的代码:

objc_msgSend(objc_msgSend([NSObject class],@selector(alloc)),@selector(init));

二、与runtime交互

bjc 从三种不同的层级上与 Runtime 系统进行交互,分别是:

通过 Objective-C 源代码通过 Foundation 框架的NSObject类定义的方法通过对 runtime 函数的直接调用。

1、Objective-C源代码

编写OC代码,程序在运行时,runtime会自动将OC转化成C语言代码。

2、NSObject的方法

Cocoa 中大多数类都继承于NSObject类,也就自然继承了它的方法。最特殊的例外是NSProxy,它是个抽象超类,它实现了一些消息转发有关的方法,可以通过继承它来实现一个其他类的替身类或是虚拟出一个不存在的类。

有的NSObject中的方法起到了抽象接口的作用,比如description方法需要你重载它并为你定义的类提供描述内容。NSObject还有些方法能在运行时获得类的信息,并检查一些特性,比如class返回对象的类;isKindOfClass:和isMemberOfClass:则检查对象是否在指定的类继承体系中;respondsToSelector:检查对象能否响应指定的消息;conformsToProtocol:检查对象是否实现了指定协议类的方法;methodForSelector:则返回指定方法实现的地址。

3、Runtime的函数

Runtime 系统是一个由一系列函数和数据结构组成,具有公共接口的动态共享库。头文件存放于/usr/include/objc目录下。许多函数允许你用纯C代码来重复实现 Objc 中同样的功能。虽然有一些方法构成了NSObject类的基础,但是你在写 Objc 代码时一般不会直接用到这些函数的,除非是写一些 Objc 与其他语言的桥接或是底层的debug工作。

三、Runtime元素认知

objc_msgSend:方法,它的真身是这样的:

id objc_msgSend ( id self, SEL op, ... );

1、objc_object

objc_msgSend第一个参数类型为id,它是一个指向类实例的指针:

// objc-private.h typedef struct objc_object *id;

objc_object定义如下:

// objc-private.h struct objc_object { private: isa_t isa; }

2、objc_class

// objc-private.h typedef struct objc_class *Class;

objc_class定义如下:

//objc-runtime-new.h struct objc_class : objc_object { // Class ISA; Class superclass; cache_t cache; // formerly cache pointer and vtable class_data_bits_t bits; // class_rw_t * plus custom rr/alloc flags }

3、isa_t

isa的指向

关于对象,其指向类对象; 关于类对象,其指向元类对象;

4、cache_t

用于快速查找方法执行函数是可增量扩展的哈希表结构是局部性原理的最佳应用

cache_t的定义如下:

//objc-runtime-new.h struct cache_t { static bucket_t *emptyBuckets(); struct bucket_t *buckets(); mask_t mask(); mask_t occupied(); void incrementOccupied(); void setBucketsAndMask(struct bucket_t *newBuckets, mask_t newMask); void initializeToEmpty(); unsigned capacity(); bool isConstantEmptyCache(); bool canBeFreed(); };

5、class_data_bits_t

class_data_bits_t主要是对class_rw_t的封装class_rw_t代表了类相关的读写信息、对class_ro_t的封装class_ro_t代表了类相关的只读信息

class_data_bits_t定义如下:

//objc-runtime-new.h struct class_data_bits_t { // Values are the FAST_ flags above. uintptr_t bits; public: class_rw_t* data() const { return (class_rw_t *)(bits & FAST_DATA_MASK); } const class_ro_t *safe_ro() { class_rw_t *maybe_rw = data(); if (maybe_rw->flags & RW_REALIZED) { // maybe_rw is rw return maybe_rw->ro(); } else { // maybe_rw is actually ro return (class_ro_t *)maybe_rw; } } };

①、class_rw_t

//objc-runtime-new.h struct class_rw_t { public: const class_ro_t *ro() const { auto v = get_ro_or_rwe(); if (slowpath(v.is<class_rw_ext_t *>())) { return v.get<class_rw_ext_t *>()->ro; } return v.get<const class_ro_t *>(); } void set_ro(const class_ro_t *ro) { auto v = get_ro_or_rwe(); if (v.is<class_rw_ext_t *>()) { v.get<class_rw_ext_t *>()->ro = ro; } else { set_ro_or_rwe(ro); } } const method_array_t methods() const { auto v = get_ro_or_rwe(); if (v.is<class_rw_ext_t *>()) { return v.get<class_rw_ext_t *>()->methods; } else { return method_array_t{v.get<const class_ro_t *>()->baseMethods()}; } } const property_array_t properties() const { auto v = get_ro_or_rwe(); if (v.is<class_rw_ext_t *>()) { return v.get<class_rw_ext_t *>()->properties; } else { return property_array_t{v.get<const class_ro_t *>()->baseProperties}; } } const protocol_array_t protocols() const { auto v = get_ro_or_rwe(); if (v.is<class_rw_ext_t *>()) { return v.get<class_rw_ext_t *>()->protocols; } else { return protocol_array_t{v.get<const class_ro_t *>()->baseProtocols}; } } };

②、class_ro_t

//objc-runtime-new.h struct class_ro_t { 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; } };

6、method_t

method_t的定义如下:

struct method_t { SEL name; const char *types; MethodListIMP 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; } }; };

①、types

四、总计

最新回复(0)