数据结构
在获取一个对象所属的类时,返回值的类型是 Class
- (Class)class;
Class
代表一个类,它是指向一个类对象的指针
typedef struct objc_class *Class;
实际上,Class
是一个 objc_class
结构体类型指针的别名
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
};
可以看到 objc_class
中有三个成员。
-
首先,
objc_class
是继承自objc_object
,也就是说类也是一个对象。其中从objc_object
继承下来的成员isa
,它包含了当前类对象所属的元类的信息。 -
其次,成员
superclass
指向了该类的父类 -
接着,成员
cache
中缓存了最近调用过的方法 -
最后,成员
bits
根据注释可以知道bits
=指向 class_rw_t 类型结构体的指针
+自定义的 rr/alloc 标识
cache_t
struct cache_t {
explicit_atomic<struct bucket_t *> _buckets;
explicit_atomic<mask_t> _mask;
uint16_t _occupied;
};
用来缓存调用过方法的是一个 cache_t
类型的结构体,共有三个成员。
第一个成员 _buckets
是一个 bucket_t
类型的数组。
第二个成员 _mask
保存着总共申请用来缓存的数量。
第三个成员 _flags
用于在 64 位时,保存一些类的相关信息。
第四个成员 _occupied
保存着目前已经使用缓存的数量。
bucket_t
struct bucket_t {
#if __arm64__
explicit_atomic<uintptr_t> _imp;
explicit_atomic<SEL> _sel;
#else
explicit_atomic<SEL> _sel;
explicit_atomic<uintptr_t> _imp;
#endif
};
bucket_t
结构体中存储了键值对,其中 _imp
是一个函数指针,指向函数的具体实现,_sel
是方法名或者方法标识。也就说 _buckets
是一个哈希表,里面通过键值对的方式保存着调用过的方法。键为 SEL
类型,值为 IMP
类型。
SEL
typedef struct objc_selector *SEL;
从声明上看 SEL
是一个 objc_selector
结构体指针的别名;从实现中找,发现 SEL
是指向一个 char *
变量,也就是说其实它就是个映射到方法的 C 字符串,可以理解为是区分方法的 ID。
SEL
只与方法名有关:
- 不同类中相同名字的方法所对应的方法选择器是相同的
- 方法名相同而变量类型不同所对应的方法选择器也是相同的
IMP
#if !OBJC_OLD_DISPATCH_PROTOTYPES
typedef void (*IMP)(void /* id, SEL, ... */ );
#else
typedef id _Nullable (*IMP)(id _Nonnull, SEL _Nonnull, ...);
#endif
IMP
是一个函数指针,它指向函数的具体实现。
class_data_bits_t
bits
中保存着类的相关信息,它是一个 class_data_bits_t
类型的结构体,
struct class_data_bits_t {
// Values are the FAST_ flags above.
uintptr_t bits;
};
这个结构体中的成员和 isa_t
结构体相同,都是通过一个 64
位的 bits
储存信息
// class is a Swift class from the pre-stable Swift ABI
#define FAST_IS_SWIFT_LEGACY (1UL<<0)
// class is a Swift class from the stable Swift ABI
#define FAST_IS_SWIFT_STABLE (1UL<<1)
// class or superclass has default retain/release/autorelease/retainCount/
// _tryRetain/_isDeallocating/retainWeakReference/allowsWeakReference
#define FAST_HAS_DEFAULT_RR (1UL<<2)
// data pointer
#define FAST_DATA_MASK 0x00007ffffffffff8UL
通过定义的宏可以知道这些位都代表了什么含义
FAST_IS_SWIFT_LEGACY
是否是来自老版稳定 Swift ABI 的 Swift 类FAST_IS_SWIFT_STABLE
是否是来自新版稳定 Swift ABI 的 Swift 类FAST_HAS_DEFAULT_RR
当前类或者父类含有默认的 retain/release/autorelease/retainCount/_tryRetain/_isDeallocating/retainWeakReference/allowsWeakReference 方法FAST_DATA_MASK
数据指针
搜索 FAST_DATA_MASK
的使用位置,可以找到一对取值/赋值方法
class_rw_t* data() const {
return (class_rw_t *)(bits & FAST_DATA_MASK);
}
void setData(class_rw_t *newData)
{
ASSERT(!data() || (newData->flags & (RW_REALIZING | RW_FUTURE)));
// Set during realization or construction only. No locking needed.
// Use a store-release fence because there may be concurrent
// readers of data and data's contents.
uintptr_t newBits = (bits & ~FAST_DATA_MASK) | (uintptr_t)newData;
atomic_thread_fence(memory_order_release);
bits = newBits;
}
通过这两方法,可以知道数据指针是一个 class_rw_t
类型的指针
class_rw_t
struct class_rw_t {
// Be warned that Symbolication knows the layout of this structure.
uint32_t flags;
uint16_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;
}
结构体 class_rw_t
名称中的 rw
代表 readwrite
,其中的成员 ro
是一个 class_ro_t
类型的指针,这里的 ro
代表 readonly
。ro
中存储了当前类在编译期就已经确定的属性、方法以及遵循的协议。而 class_rw_t
提供了运行时对类拓展的能力,其中的 methods
、properties
、protocols
保存着通过 Category 在运行时添加的方法、属性及协议。
成员 methods
、properties
、protocols
对应的 method_array_t
、property_array_t
、protocol_array_t
类型都是继承自 list_array_tt<Element, List>
,该类型可以保存三种类型的值:
- 空值;
- 指向单个列表的指针;
- 指向列表的指针数组。
通过第 3 种类型也就是二维数组类型,可以实现数据的扩展。例如,method_array_t
是一个数组,其中保存的元素是 method_list_t
,而 method_list_t
也是一个数组,其中保存的元素是 method_t
。
class_ro_t
相对的,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;
};
结构体中的成员 baseMethodList
、baseProperties
、baseProtocols
和 ivar_list_t
对应的 method_list_t
、property_list_t
、protocol_list_t
和 ivar_list_t
类型都是继承自 entsize_list_tt
,一个泛型的数组结构,没有扩展功能。
类的初始化
类在运行时第一次初始化时会调用 realizeClass...
系列方法
ro = (const class_ro_t *)cls->data();
if (ro->flags & RO_FUTURE) {
// This was a future class. rw data is already allocated. rw = cls->data();
ro = cls->data()->ro;
cls->changeInfo(RW_REALIZED|RW_REALIZING, RW_FUTURE);
} else {
// Normal class. Allocate writeable class data. rw = (class_rw_t *)calloc(sizeof(class_rw_t), 1);
rw->ro = ro;
rw->flags = RW_REALIZED|RW_REALIZING;
cls->setData(rw);
}
在该方法的实现中,可以知道在编译期间类的结构中的 class_data_bits_t *data
指向的是一个 class_ro_t *
。在运行时的时候调用该初始化方法时,首先为 class_rw_t *
申请内存空间,然后将 class_ro_t *
赋值给 rw->ro
,接着设置 class_rw_t *
的标志位标识状态,最后将创建好的 class_rw_t *
赋值给类结构。
分类
Category 提供了在运行时动态的向已经存在的类中添加方法、协议和属性的功能
typedef struct category_t *Category;
struct category_t {
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;
};
加载分类
static void
attachCategories(Class cls, const locstamped_category_t *cats_list, uint32_t cats_count,
int flags)
{
constexpr uint32_t ATTACH_BUFSIZ = 64;
method_list_t *mlists[ATTACH_BUFSIZ];
uint32_t mcount = 0;
bool fromBundle = NO;
bool isMeta = (flags & ATTACH_METACLASS);
auto rw = cls->data();
for (uint32_t i = 0; i < cats_count; i++) {
auto& entry = cats_list[i];
method_list_t *mlist = entry.cat->methodsForMeta(isMeta);
if (mlist) {
if (mcount == ATTACH_BUFSIZ) {
prepareMethodLists(cls, mlists, mcount, NO, fromBundle);
rw->methods.attachLists(mlists, mcount);
mcount = 0;
}
mlists[ATTACH_BUFSIZ - ++mcount] = mlist;
fromBundle |= entry.hi->isBundle();
}
}
if (mcount > 0) {
prepareMethodLists(cls, mlists + ATTACH_BUFSIZ - mcount, mcount, NO, fromBundle);
rw->methods.attachLists(mlists + ATTACH_BUFSIZ - mcount, mcount);
if (flags & ATTACH_EXISTING) flushCaches(cls);
}
}
原来的方法中包含了对分类中方法、代理和属性的处理,但原理相同,为了减少篇幅,只保留对方法的处理:
- 声明一个大小为 64,元素类型为
method_list_t *
的二维数组类型的临时变量mlists
- 遍历分类数组,获取分类中的方法列表
mlist
,从后向前的添加到mlists
中 - 如果
mlists
数组在遍历过程中存满,则合并到rw->methods
中,否则等待遍历完合并
合并方法
void attachLists(List* const * addedLists, uint32_t addedCount) {
if (addedCount == 0) return;
if (hasArray()) {
// many lists -> many lists
uint32_t oldCount = array()->count;
uint32_t newCount = oldCount + addedCount;
setArray((array_t *)realloc(array(), array_t::byteSize(newCount)));
array()->count = newCount;
memmove(array()->lists + addedCount, array()->lists,
oldCount * sizeof(array()->lists[0]));
memcpy(array()->lists, addedLists,
addedCount * sizeof(array()->lists[0]));
}
else if (!list && addedCount == 1) {
// 0 lists -> 1 list
list = addedLists[0];
}
else {
// 1 list -> many lists
List* oldList = list;
uint32_t oldCount = oldList ? 1 : 0;
uint32_t newCount = oldCount + addedCount;
setArray((array_t *)malloc(array_t::byteSize(newCount)));
array()->count = newCount;
if (oldList) array()->lists[addedCount] = oldList;
memcpy(array()->lists, addedLists,
addedCount * sizeof(array()->lists[0]));
}
}
在合并时,大致有两种情况。一种是当前数组中为空,那就直接指向新添加的数组;另一种是当前数组中已经有数据:
- 先通过
realloc()
方法为原数组扩充空间 - 再将原数组的元素利用
memmove()
方法移动到新申请空间的后面 - 最后使用
memcpy()
方法把新数组复制到新空间的前面
方法覆盖
通过上面两段代码,可以发现两点:
- 分类中如果重写了方法,并不会覆盖原有方法
- 之所以在使用时出现“覆盖”原方法的现象,是因为在方法列表中分类中的方法被添加到了原方法的前面
- 如果某个类的多个分类都重写了同一个方法,那么,最后执行的是最后被遍历到的分类(也就是最后被添加到项目中的分类)中的方法
函数
objc_class
data
获取类中的数据
// 返回值是一个 class_rw_t 类型的指针,说明类中的数据是以 class_rw_t 类型保存的
class_rw_t *data() const {
// 通过调用成员 bits 的公共函数 data() 获取数据
return bits.data();
}
setData
设置类中的数据
// 设置值要求是一个 class_rw_t 类型的指针
void setData(class_rw_t *newData) {
// 通过调用成员 bits 的公共函数 setData() 设置数据
bits.setData(newData);
}
setInfo
设置标志位信息
void setInfo(uint32_t set) {
// 必须满足要么是一个未实现的懒加载类,要么已经实现
ASSERT(isFuture() || isRealized());
// 先调用 data 函数获取类的 class_rw_t 实例数据
// 再调动 class_rw_t 实例的 setFlags 函数设置标志位信息
data()->setFlags(set);
}
clearInfo
清除标志位信息
void clearInfo(uint32_t clear) {
// 必须满足要么是一个未实现的懒加载类,要么已经实现
ASSERT(isFuture() || isRealized());
// 先调用 data 函数获取类的 class_rw_t 实例数据
// 再调动 class_rw_t 实例的 clearFlags 函数清除标志位信息
data()->clearFlags(clear);
}
changeInfo
设置和清除标志位信息
void changeInfo(uint32_t set, uint32_t clear) {
// 必须满足要么是一个未实现的懒加载类,要么已经实现
ASSERT(isFuture() || isRealized());
// 要设置的标志位和要清除的标志位不能是同一个
ASSERT((set & clear) == 0);
// 先调用 data 函数获取类的 class_rw_t 实例数据
// 再调动 class_rw_t 实例的 changeFlags 函数设置和清除标志位信息
data()->changeFlags(set, clear);
}
hasCustomRR
获取当前类及其超类是否自定义了 retain/release/autorelease/retainCount/_tryRetain/_isDeallocating/retainWeakReference/allowsWeakReference 这些方法之一
bool hasCustomRR() const {
// 调用成员 bits 的 getBit 函数获取 FAST_HAS_DEFAULT_RR 标志位的数据
return !bits.getBit(FAST_HAS_DEFAULT_RR);
}
setHasDefaultRR
标识当前类及其超类没有自定义retain/release/autorelease/retainCount/_tryRetain/_isDeallocating/retainWeakReference/allowsWeakReference 这些方法之一
void setHasDefaultRR() {
// 调用成员 bits 的 setBits 函数设置 FAST_HAS_DEFAULT_RR 标志位的数据
bits.setBits(FAST_HAS_DEFAULT_RR);
}
setHasCustomRR
标识当前类及其超类自定义了retain/release/autorelease/retainCount/_tryRetain/_isDeallocating/retainWeakReference/allowsWeakReference 这些方法之一
void setHasCustomRR() {
// 调用成员 bits 的 clearBits 函数将 FAST_HAS_DEFAULT_RR 标志位的数据置零
bits.clearBits(FAST_HAS_DEFAULT_RR);
}
hasCustomAWZ
获取当前类及其超类是否自定义了 alloc/allocWithZone: 这些方法之一
bool hasCustomAWZ() const {
// 调用成员 cache 的 getBit 函数获取 FAST_CACHE_HAS_DEFAULT_AWZ 标志位的数据
return !cache.getBit(FAST_CACHE_HAS_DEFAULT_AWZ);
}
setHasDefaultAWZ
标识当前类及其超类没有自定义 alloc/allocWithZone: 这些方法之一
void setHasDefaultAWZ() {
// 调用成员 cache 的 setBits 函数设置 FAST_CACHE_HAS_DEFAULT_AWZ 标志位的数据
cache.setBit(FAST_CACHE_HAS_DEFAULT_AWZ);
}
setHasCustomAWZ
标识当前类及其超类自定义了 alloc/allocWithZone: 这些方法之一
void setHasCustomAWZ() {
// 调用成员 cache 的 clearBits 函数将 FAST_CACHE_HAS_DEFAULT_AWZ 标志位的数据置零
cache.clearBit(FAST_CACHE_HAS_DEFAULT_AWZ);
}
hasCustomCore
获取当前类及其超类是否自定义了 new/self/class/respondsToSelector/isKindOfClass 这些方法之一
bool hasCustomCore() const {
// 调用成员 cache 的 getBit 函数获取 FAST_CACHE_HAS_DEFAULT_CORE 标志位的数据
return !cache.getBit(FAST_CACHE_HAS_DEFAULT_CORE);
}
setHasDefaultCore
标识当前类及其超类没有自定义 new/self/class/respondsToSelector/isKindOfClass 这些方法之一
void setHasDefaultCore() {
// 调用成员 cache 的 setBits 函数设置 FAST_CACHE_HAS_DEFAULT_CORE 标志位的数据
return cache.setBit(FAST_CACHE_HAS_DEFAULT_CORE);
}
setHasCustomCore
标识当前类及其超类自定义了 new/self/class/respondsToSelector/isKindOfClass 这些方法之一
void setHasCustomCore() {
// 调用成员 cache 的 clearBits 函数将 FAST_CACHE_HAS_DEFAULT_CORE 标志位的数据置零
return cache.clearBit(FAST_CACHE_HAS_DEFAULT_CORE);
}
hasCxxCtor
获取当前类及其超类是否有 .cxx_construct C++ 构造方法的实现
bool hasCxxCtor() {
// 当前类必须已经实现
ASSERT(isRealized());
// 调用成员 cache 的 getBit 函数获取 FAST_CACHE_HAS_CXX_CTOR 标志位的数据
return cache.getBit(FAST_CACHE_HAS_CXX_CTOR);
}
setHasCxxCtor
标识当前类及其超类有 .cxx_construct C++ 构造方法的实现
void setHasCxxCtor() {
// 调用成员 cache 的 setBits 函数设置 FAST_CACHE_HAS_CXX_CTOR 标志位的数据
cache.setBit(FAST_CACHE_HAS_CXX_CTOR);
}
hasCxxDtor
获取当前类及其超类是否有 .cxx_destruct C++ 析构方法的实现
bool hasCxxDtor() {
// 当前类必须已经实现
ASSERT(isRealized());
// 调用成员 cache 的 getBit 函数获取 FAST_CACHE_HAS_CXX_DTOR 标志位的数据
return cache.getBit(FAST_CACHE_HAS_CXX_DTOR);
}
setHasCxxDtor
标识当前类及其超类有 .cxx_destruct C++ 析构方法的实现
void setHasCxxDtor() {
// 调用成员 cache 的 setBits 函数设置 FAST_CACHE_HAS_CXX_DTOR 标志位的数据
cache.setBit(FAST_CACHE_HAS_CXX_DTOR);
}
instancesRequireRawIsa
获取类的实例对象是否需要原始 isa(isa 直接指向类)
bool instancesRequireRawIsa() {
// 调用成员 cache 的 getBit 函数获取 FAST_CACHE_REQUIRES_RAW_ISA 标志位的数据
return cache.getBit(FAST_CACHE_REQUIRES_RAW_ISA);
}
setInstancesRequireRawIsa
标识类的实例对象需要原始 isa(isa 直接指向类)
void setInstancesRequireRawIsa() {
// 调用成员 cache 的 setBits 函数设置 FAST_CACHE_REQUIRES_RAW_ISA 标志位的数据
cache.setBit(FAST_CACHE_REQUIRES_RAW_ISA);
}
setInstancesRequireRawIsaRecursively
将当前类及其所有子类,全部标识为其类的实例对象需要原始 isa(isa 直接指向类)
void setInstancesRequireRawIsaRecursively(bool inherited = false);
void objc_class::setInstancesRequireRawIsaRecursively(bool inherited)
{
// 获取当前类对象
Class cls = (Class)this;
// 加锁
runtimeLock.assertLocked();
// 如果当前类的实例对象已经被要求是原始 isa,就直接返回
if (instancesRequireRawIsa()) return;
// 遍历当前类及其子类
foreach_realized_class_and_subclass(cls, [=](Class c){
// 如果该类的实例对象已经被要求是原始 isa,就直接跳过
if (c->instancesRequireRawIsa()) {
return false;
}
// 标识该类的实例对象需要是原始 isa 类型
c->setInstancesRequireRawIsa();
// 打印日志相关
if (PrintRawIsa) c->printInstancesRequireRawIsa(inherited || c != cls);
return true;
});
}
printInstancesRequireRawIsa
void printInstancesRequireRawIsa(bool inherited);
void
objc_class::printInstancesRequireRawIsa(bool inherited)
{
// 必须已经标识为要打印原始 isa
ASSERT(PrintRawIsa);
// 必须是该类的实例对象已经被要求是原始 isa
ASSERT(instancesRequireRawIsa());
// 打印原始 isa 相关信息
_objc_inform("RAW ISA: %s%s%s", nameForLogging(),
isMetaClass() ? " (meta)" : "",
inherited ? " (inherited)" : "");
}
canAllocNonpointer
获取当前类的实例对象可否以 Nonpointer 类型创建
bool canAllocNonpointer() {
// 必须是正常类,而非懒加载类
ASSERT(!isFuture());
// 如果该类的实例对象不要求是原始 isa 类型就可以用 Nonpointer 类型
return !instancesRequireRawIsa();
}
isSwiftStable
获取当前类是否为 Swift 最新稳定类
bool isSwiftStable() {
// 调用成员 bits 的 isSwiftStable 函数获取
return bits.isSwiftStable();
}
isSwiftLegacy
获取当前类是否为 Swift 老版稳定类
bool isSwiftLegacy() {
// 调用成员 bits 的 isSwiftLegacy 函数获取
return bits.isSwiftLegacy();
}
isAnySwift
获取当前类是否为 Swift 类
bool isAnySwift() {
// 调用成员 bits 的 isAnySwift 函数获取
return bits.isAnySwift();
}
isSwiftStable_ButAllowLegacyForNow
获取当前类是否为 Swift 类
bool isSwiftStable_ButAllowLegacyForNow() {
// 调用成员 bits 的 isSwiftStable_ButAllowLegacyForNow 函数获取
// 其中 isSwiftStable_ButAllowLegacyForNow 函数内部调用了 isAnySwift 函数
return bits.isSwiftStable_ButAllowLegacyForNow();
}
isStubClass
获取当前类是否为存根类
bool isStubClass() const {
// 获取类对象的 isa 数据
uintptr_t isa = (uintptr_t)isaBits();
// 如果 isa 数据在 5 位以内就是存根类
return 1 <= isa && isa < 16;
}
isUnfixedBackwardDeployingStableSwift
判断是否为未修复的向后兼容的老版 Swift 稳定类
bool isUnfixedBackwardDeployingStableSwift() {
// Only classes marked as Swift legacy need apply.
// 只处理老版 Swift 稳定类
if (!bits.isSwiftLegacy()) return false;
// Check the true legacy vs stable distinguisher.
// The low bit of Swift's ClassFlags is SET for true legacy
// and UNSET for stable pretending to be legacy.
// 获取 Swift 类的标志位。即类对象地址的第 1 位的值
uint32_t swiftClassFlags = *(uint32_t *)(&bits + 1);
// 根据标志位判断是否为真的老版 Swift 稳定类
bool isActuallySwiftLegacy = bool(swiftClassFlags & 1);
// 返回结果
return !isActuallySwiftLegacy;
}
fixupBackwardDeployingStableSwift
修复向后兼容的老版 Swift 稳定类的标志位
void fixupBackwardDeployingStableSwift() {
// 如果是未修复的向后兼容的老版 Swift 稳定类
if (isUnfixedBackwardDeployingStableSwift()) {
// Class really is stable Swift, pretending to be pre-stable.
// Fix its lie.
// 设置其标志位为稳定版 Swift 类,并清除老版 Swift 稳定版标志位
bits.setIsSwiftStable();
}
}
swiftMetadataInitializer
获取 Swift 元类初始化器
_objc_swiftMetadataInitializer swiftMetadataInitializer() {
// 调用成员 bits 的 swiftMetadataInitializer 函数获取
return bits.swiftMetadataInitializer();
}
hasAutomaticIvars
获取该类的成员变量是否为自动布局
bool hasAutomaticIvars() {
// 通过 data 函数获取保存在 ro 成员中的 flags 标志位数据
// 获取其标志位 RO_IS_ARC 和 RO_HAS_WEAK_WITHOUT_ARC 中保存的数据
// 如果标志位标示该类是用 ARC 编译的类,或者类不是 ARC 编译的类,但具有 ARC 样式的弱 ivar 布局,就返回 true
return data()->ro->flags & (RO_IS_ARC | RO_HAS_WEAK_WITHOUT_ARC);
}
isARC
获取该类的成员变量是否由 ARC 管理
bool isARC() {
// 通过 data 函数获取保存在 ro 成员中的 flags 标志位数据
// 获取其标志位 RO_IS_ARC 中保存的数据
return data()->ro->flags & RO_IS_ARC;
}
forbidsAssociatedObjects
获取该类是否禁止其实例对象关联对象
bool forbidsAssociatedObjects() {
// 通过 data 函数获取保存在 ro 成员中的 flags 标志位数据
// 获取其标志位 RW_FORBIDS_ASSOCIATED_OBJECTS 中保存的数据
return (data()->flags & RW_FORBIDS_ASSOCIATED_OBJECTS);
}
shouldGrowCache
获取该类是否要增加缓存
bool shouldGrowCache() {
// 直接返回 true,也就是一定会增加缓存
return true;
}
setShouldGrowCache
设置该类是否要增加缓存
void setShouldGrowCache(bool) {
// 无实现
// fixme good or bad for memory use?
}
isInitializing
获取该类是否正在初始化
bool isInitializing() {
// 通过 getMeta 函数获取该类的元类
// 通过 data 函数获取该类元类的数据
// 获取其标志位 RW_INITIALIZING 中保存的数据
return getMeta()->data()->flags & RW_INITIALIZING;
}
setInitializing
设置该类是否正在初始化的状态
void setInitializing() {
// 当前类不能是元类
ASSERT(!isMetaClass());
// 通过 ISA 函数获取该类的元类
// 通过 setInfo 函数设置其元类 RW_INITIALIZING 标志位的数据
ISA()->setInfo(RW_INITIALIZING);
}
isInitialized
获取该类是否已经初始化
bool isInitialized() {
// 通过 getMeta 函数获取该类的元类
// 通过 data 函数获取该类元类的数据
// 获取其标志位 RW_INITIALIZED 中保存的数据
return getMeta()->data()->flags & RW_INITIALIZED;
}
setInitialized
设置该类是否已经初始化的状态
void setInitialized();
void
objc_class::setInitialized()
{
Class metacls;
Class cls;
// 当前类不能是元类
ASSERT(!isMetaClass());
// 获取当前类的类对象并保存到临时变量中
cls = (Class)this;
// 获取当前类的元类并保存到临时变量中
metacls = cls->ISA();
// 加锁
mutex_locker_t lock(runtimeLock);
// Special cases:
// - NSObject AWZ class methods are default.
// - NSObject RR class and instance methods are default.
// - NSObject Core class and instance methods are default.
// adjustCustomFlagsForMethodChange() also knows these special cases.
// attachMethodLists() also knows these special cases.
// 扫描当前类的 +alloc / +allocWithZone: 方法是否为默认实现,并设置标志位进行标识
objc::AWZScanner::scanInitializedClass(cls, metacls);
// 扫描当前类的 retain/release/autorelease/retainCount/_tryRetain/_isDeallocating/retainWeakReference/allowsWeakReference 方法是否为默认实现,并设置标志位进行标识
objc::RRScanner::scanInitializedClass(cls, metacls);
// 扫描当前类的 +new, ±class, ±self, ±isKindOfClass:, ±respondsToSelector 方法是否为默认实现,并设置标志位进行标识
objc::CoreScanner::scanInitializedClass(cls, metacls);
// Update the +initialize flags.
// Do this last.
// 通过 changeInfo 函数设置其元类 RW_INITIALIZED 标志位的数据,并清除 RW_INITIALIZING 标志位的数据
metacls->changeInfo(RW_INITIALIZED, RW_INITIALIZING);
}
isLoadable
获取该类是否为可加载的
bool isLoadable() {
// 必须是已经实现的类
ASSERT(isRealized());
// 任何一个类都注册了 +load 方法,所以都是可加载的,就返回 true
return true; // any class registered for +load is definitely loadable
}
getLoadMethod
获取当前类的 +load 方法实现
IMP getLoadMethod();
IMP
objc_class::getLoadMethod()
{
// 加锁
runtimeLock.assertLocked();
const method_list_t *mlist;
// 当前类必须已实现
ASSERT(isRealized());
// 当前类对象所属的类必须已实现
ASSERT(ISA()->isRealized());
// 当前类不能是元类
ASSERT(!isMetaClass());
// 当前类对象所属的类必须是元类
ASSERT(ISA()->isMetaClass());
// 通过 ISA 函数获取该类的元类
// 通过 data 函数设置其元类数据
// 通过调用其元类 ro 成员的 baseMethods 函数获取在编译时生成的方法列表
mlist = ISA()->data()->ro->baseMethods();
// 遍历类方法列表,如果类方法的 SEL 为 load,就返回其 IMP
if (mlist) {
for (const auto& meth : *mlist) {
const char *name = sel_cname(meth.name);
if (0 == strcmp(name, "load")) {
return meth.imp;
}
}
}
return nil;
}
isRealized
获取该类是否已实现
bool isRealized() const {
// 前提为当前类不是存根类
// 通过 data 函数获取该类的数据
// 获取其标志位 RW_REALIZED 中保存的数据
return !isStubClass() && (data()->flags & RW_REALIZED);
}
isFuture
获取该类是否为懒加载类
bool isFuture() const {
// 通过 data 函数获取该类的数据
// 获取其标志位 RW_FUTURE 中保存的数据
return data()->flags & RW_FUTURE;
}
isMetaClass
获取该类是否为元类
bool isMetaClass() {
// 当前类必须存在
ASSERT(this);
// 当前类必须已实现
ASSERT(isRealized());
#if FAST_CACHE_META
// 通过其 cache 成员的 getBit 函数获取标志位 FAST_CACHE_META 中保存的数据
return cache.getBit(FAST_CACHE_META);
#else
return data()->ro->flags & RO_META;
#endif
}
isMetaClassMaybeUnrealized
获取该类是否为元类,但该类可能还未实现
bool isMetaClassMaybeUnrealized() {
// 调用成员 bits 的 safe_ro 函数安全的获取其编译时产生 ro 数据
// 获取其标志位 RO_META 中保存的数据
return bits.safe_ro()->flags & RO_META;
}
getMeta
获取该类的元类
Class getMeta() {
// 如果当前类就是元类,便返回自己
if (isMetaClass()) return (Class)this;
// 否则通过 ISA 函数获取其元类
else return this->ISA();
}
isRootClass
获取该类是否为根类
bool isRootClass() {
// 如果当前类的 superclass 成员为空,那当前类便是根类
return superclass == nil;
}
isRootMetaclass
获取该类是否为根元类
bool isRootMetaclass() {
// 如果当前类对象所属的类就是自己,那当前类便是根元类
return ISA() == (Class)this;
}
mangledName
获取该类的修饰别名
const char *mangledName() {
// fixme can't assert locks here
// 当前类必须存在
ASSERT(this);
if (isRealized() || isFuture()) {
// 如果当前类已实现,或者是一个懒加载类
// 通过 data 函数获取保存在 ro 成员中 name 的数据
return data()->ro->name;
} else {
// 否则,先通过 data 函数获取 class_ro_t 类型的数据,然后获取数据中 name 的值
return ((const class_ro_t *)data())->name;
}
}
demangledName
获取该类的解析别名
const char *demangledName();
mutex_t DemangleCacheLock;
static objc::DenseSet<const char *> *DemangleCache;
const char *
objc_class::demangledName()
{
// Return previously demangled name if available.
// 如果当前类已实现,或者为懒加载类
if (isRealized() || isFuture()) {
// 通过 data 函数获取该类的数据
// 获取数据中成员 demangledName 保存的值
// 如果有值的话,直接返回
if (data()->demangledName) return data()->demangledName;
}
// Try demangling the mangled name.
// 获取当前类的修饰别名
const char *mangled = mangledName();
// 生成符合 Swift-v1-mangled 样式的解析别名
char *de = copySwiftV1DemangledName(mangled);
// 如果当前类已实现,或者为懒加载类
if (isRealized() || isFuture()) {
// Class is already realized or future.
// Save demangling result in rw data.
// We may not own runtimeLock so use an atomic operation instead.
// 将生成的解析别名保存到 rw 的 demangledName 成员中
if (! OSAtomicCompareAndSwapPtrBarrier(nil, (void*)(de ?: mangled),
(void**)&data()->demangledName))
{
// 如果没保存成功,就将解析别名释放掉
if (de) free(de);
}
// 返回即通过
return data()->demangledName;
}
// Class is not yet realized.
// 如果没能生成符合 Swift-v1-mangled 样式的解析别名,就直接返回当前类的修饰别名
if (!de) {
// Name is not mangled. Return it without caching.
return mangled;
}
// Class is not yet realized and name is mangled.
// Allocate the name but don't save it in the class.
// Save the name in a side cache instead to prevent leaks.
// When the class is actually realized we may allocate a second
// copy of the name, but we don't care.
// (Previously we would try to realize the class now and save the
// name there, but realization is more complicated for Swift classes.)
// Only objc_copyClassNamesForImage() should get here.
// fixme lldb's calls to class_getName() can also get here when
// interrogating the dyld shared cache. (rdar://27258517)
// fixme runtimeLock.assertLocked();
// fixme ASSERT(realize);
const char *cached;
{
// 加锁
mutex_locker_t lock(DemangleCacheLock);
// 如果没有 DemangleCache 容器,就生成一个
if (!DemangleCache) {
DemangleCache = new objc::DenseSet<const char *>{};
}
// 将解析别名插入到 DemangleCache 首位
cached = *DemangleCache->insert(de).first;
}
// 如果没能成功缓存,就将解析别名释放掉
if (cached != de) free(de);
// 返回缓存中保存的解析别名
return cached;
}
nameForLogging
获取该类用于显示/打印的名称
const char *nameForLogging();
const char *
objc_class::nameForLogging()
{
// Handle the easy case directly.
// 如果当前类已实现,或者为懒加载类
if (isRealized() || isFuture()) {
// 通过 data 函数获取该类的数据中成员 demangledName 有值的话直接返回
if (data()->demangledName) return data()->demangledName;
}
char *result;
// 获取当前类的修饰别名
const char *name = mangledName();
// 获取当前类符合 Swift-v1-mangled 样式的解析别名
char *de = copySwiftV1DemangledName(name);
// 如果有解析别名,就返回解析别名
if (de) result = de;
// 否则就返回修饰别名
else result = strdup(name);
// 将名称保存在线程本地FIFO缓冲区中
saveTemporaryString(result);
// 返回结果
return result;
}
unalignedInstanceStart
获取该类未经过字节对齐处理前的成员变量布局的开始位置
uint32_t unalignedInstanceStart() const {
// 当前类必须已实现
ASSERT(isRealized());
// 通过 data 函数获取该类的数据
// 获取数据中的 ro 成员
// 返回 ro 成员 instanceStart 中保存的值
return data()->ro->instanceStart;
}
alignedInstanceStart
获取该类已经过对齐处理后的成员变量布局的开始位置
uint32_t alignedInstanceStart() const {
// 对当前类未经过字节对齐处理前的成员变量布局的开始位置进行字节对齐处理,并返回
return word_align(unalignedInstanceStart());
}
unalignedInstanceSize
获取该类未经过字节对齐处理前的实例对象内存布局的大小
uint32_t unalignedInstanceSize() const {
// 当前类必须已实现
ASSERT(isRealized());
// 通过 data 函数获取该类的数据
// 获取数据中的 ro 成员
// 返回 ro 成员 instanceSize 中保存的值
return data()->ro->instanceSize;
}
alignedInstanceSize
获取该类已经过对齐处理后的实例对象内存布局的大小
uint32_t alignedInstanceSize() const {
// 对当前类未经过字节对齐处理前的实例对象内存布局的大小进行字节对齐处理,并返回
return word_align(unalignedInstanceSize());
}
instanceSize
获取该类实例对象占用的内存大小
size_t instanceSize(size_t extraBytes) const {
// 调用成员 cache 的 hasFastInstanceSize 函数获取实例对象内存布局的大小,如果有就直接返回
if (fastpath(cache.hasFastInstanceSize(extraBytes))) {
return cache.fastInstanceSize(extraBytes);
}
// 获取当前类已经过对齐处理后的实例对象内存布局的大小,并加上传入的参数
size_t size = alignedInstanceSize() + extraBytes;
// CF requires all objects be at least 16 bytes.
// 实例对象内存布局的大小最小为 16 字节
if (size < 16) size = 16;
// 返回大小
return size;
}
setInstanceSize
设置该类实例对象占用的内存大小
void setInstanceSize(uint32_t newSize) {
// 当前类必须已实现
ASSERT(isRealized());
// 当前类设置过正在实现标识
ASSERT(data()->flags & RW_REALIZING);
// 如果新大小与 instanceSize 中保存的不同
if (newSize != data()->ro->instanceSize) {
// rw 的 ro 成员必须是 class_ro_t 类型的数据
ASSERT(data()->flags & RW_COPIED_RO);
// 将新数据保存到 instanceSize 中
*const_cast<uint32_t *>(&data()->ro->instanceSize) = newSize;
}
// 调用成员 cache 的 setFastInstanceSize 函数保存新的实例对象内存大小
cache.setFastInstanceSize(newSize);
}
cache_t
emptyBuckets
获取一个空容器
static bucket_t *emptyBuckets();
struct bucket_t *cache_t::emptyBuckets()
{
// 获取一个空容器,转换成 bucket_t * 类型后返回
return (bucket_t *)&_objc_empty_cache;
}
buckets
获取当前容器
struct bucket_t *buckets();
struct bucket_t *cache_t::buckets()
{
// 调用成员 `_buckets` 的 load 函数获取当前正在使用的容器
return _buckets.load(memory_order::memory_order_relaxed);
}
mask
获取当前缓存大小
mask_t mask();
mask_t cache_t::mask() {
// 调用成员 `_mask` 的 load 函数获取当前的缓存大小
return _mask.load(memory_order::memory_order_relaxed);
}
occupied
获取当前已使用多少缓存
mask_t occupied();
mask_t cache_t::occupied() {
// 直接返回成员 `_occupied`
return _occupied;
}
incrementOccupied
增加缓存的数量
void incrementOccupied();
void cache_t::incrementOccupied() {
// 成员 `_occupied` 计数 +1
_occupied++;
}
setBucketsAndMask
重新设置容器和掩码
void setBucketsAndMask(struct bucket_t *newBuckets, mask_t newMask);
void cache_t::setBucketsAndMask(struct bucket_t *newBuckets, mask_t newMask) {
// objc_msgSend uses mask and buckets with no locks.
// It is safe for objc_msgSend to see new buckets but old mask.
// (It will get a cache miss but not overrun the buckets' bounds).
// It is unsafe for objc_msgSend to see old buckets and new mask.
// Therefore we write new buckets, wait a lot, then write new mask.
// objc_msgSend reads mask first, then buckets.
#ifdef __arm__
// ensure other threads see buckets contents before buckets pointer
mega_barrier();
_buckets.store(newBuckets, memory_order::memory_order_relaxed);
// ensure other threads see new buckets before new mask
mega_barrier();
_mask.store(newMask, memory_order::memory_order_relaxed);
_occupied = 0;
#elif __x86_64__ || i386
// ensure other threads see buckets contents before buckets pointer
// 保存新的容器
_buckets.store(newBuckets, memory_order::memory_order_release);
// ensure other threads see new buckets before new mask
// 保存新的掩码
_mask.store(newMask, memory_order::memory_order_release);
// 缓存计数置空
_occupied = 0;
#else
#error Don't know how to do setBucketsAndMask on this architecture. #endif }
initializeToEmpty
初始化缓存
void initializeToEmpty();
void cache_t::initializeToEmpty() {
// 将当前内存中所有字节置空
bzero(this, sizeof(*this));
// 将容器置空
_buckets.store((bucket_t *)&_objc_empty_cache, memory_order::memory_order_relaxed);
}
capacity
获取当前缓存容量
unsigned capacity();
unsigned cache_t::capacity()
{
// 调用 mask 获取缓存大小,如果有就 +1 后返回,没有就返回 0
return mask() ? mask()+1 : 0;
}
isConstantEmptyCache
获取当前缓存是否为空
bool isConstantEmptyCache();
bool cache_t::isConstantEmptyCache()
{
// 一共有两个判断条件
// 一个是没有使用量
// 一个是空容器
return
occupied() == 0 &&
buckets() == emptyBucketsForCapacity(capacity(), false);
}
canBeFreed
获取当前缓存是否可以释放
bool canBeFreed();
bool cache_t::canBeFreed() {
// 如果缓存不为空,就可以释放
return !isConstantEmptyCache();
}
getBit
获取指定标志位数据
bool getBit(uint16_t flags) const {
// 通过位与获取成员 _flags 中指定位的数据
return _flags & flags;
}
setBit
设置指定标志位数据
void setBit(uint16_t set) {
// 原子性的设置成员 _flags 中指定位的数据
__c11_atomic_fetch_or((_Atomic(uint16_t) *)&_flags, set, __ATOMIC_RELAXED);
}
clearBit
清空指定标志位数据
void clearBit(uint16_t clear) {
// 原子性的清空成员 _flags 中指定位的数据
__c11_atomic_fetch_and((_Atomic(uint16_t) *)&_flags, ~clear, __ATOMIC_RELAXED);
}
hasFastInstanceSize
是否保存有快速获取实例变量的内存布局大小
bool hasFastInstanceSize(size_t extra) const {
// 如果参数 extra 是编译时常量,并且为 0,那么就取成员 _flags 掩码 FAST_CACHE_ALLOC_MASK16 的值
if (__builtin_constant_p(extra) && extra == 0) {
return _flags & FAST_CACHE_ALLOC_MASK16;
}
// 否则就取成员 _flags 掩码 FAST_CACHE_ALLOC_MASK 的值
return _flags & FAST_CACHE_ALLOC_MASK;
}
fastInstanceSize
快速获取实例变量的内存布局大小
size_t fastInstanceSize(size_t extra) const {
// 成员 _flags 中必须有保存
ASSERT(hasFastInstanceSize(extra));
if (__builtin_constant_p(extra) && extra == 0) {
// 如果参数 extra 是编译时常量,并且为 0,那么就取成员 _flags 掩码 FAST_CACHE_ALLOC_MASK16 的值
return _flags & FAST_CACHE_ALLOC_MASK16;
} else {
// 否则就取成员 _flags 掩码 FAST_CACHE_ALLOC_MASK 的值
// 再加上传入的参数
// 接着减去通过 setFastInstanceSize 添加的 FAST_CACHE_ALLOC_DELTA16
// 最后通过 align16 函数对结果进行 16 字节对齐
size_t size = _flags & FAST_CACHE_ALLOC_MASK;
// remove the FAST_CACHE_ALLOC_DELTA16 that was added
// by setFastInstanceSize
return align16(size + extra - FAST_CACHE_ALLOC_DELTA16);
}
}
setFastInstanceSize
设置快速获取实例变量的内存布局大小
void setFastInstanceSize(size_t newSize) {
// Set during realization or construction only. No locking needed.
// 通过位与 FAST_CACHE_ALLOC_MASK 的反码,将成员 _flags 的数据初始化
uint16_t newBits = _flags & ~FAST_CACHE_ALLOC_MASK;
uint16_t sizeBits;
// Adding FAST_CACHE_ALLOC_DELTA16 allows for FAST_CACHE_ALLOC_MASK16
// to yield the proper 16byte aligned allocation size with a single mask
// 先通过 word_align 函数将传入的参数进行字节对齐
// 然后加上 FAST_CACHE_ALLOC_DELTA16 掩码,
// 这么做的目的是可以通过 FAST_CACHE_ALLOC_MASK16 使用单个掩码获取正确的以 16字节对齐内存布局大小
sizeBits = word_align(newSize) + FAST_CACHE_ALLOC_DELTA16;
// 最后位与 FAST_CACHE_ALLOC_MASK 掩码
sizeBits &= FAST_CACHE_ALLOC_MASK;
// 只有当传入的大小没有从保存的位数中溢出,才通过位或运算保存到 newBits。否则,newBits 中保存的是初始化的数据
if (newSize <= sizeBits) {
newBits |= sizeBits;
}
// 成员 _flags 保存处理好的数据
_flags = newBits;
}
bytesForCapacity
获取指定缓存容量占用的字节大小
static size_t bytesForCapacity(uint32_t cap);
size_t cache_t::bytesForCapacity(uint32_t cap)
{
// fixme put end marker inline when capacity+1 malloc is inefficient
// 先获取结构体 bucket_t 占用的内存字节大小
// 再乘上传入的缓存容量 + 1 后的值
return sizeof(bucket_t) * (cap + 1);
}
endMarker
获取缓存的结束标识
static struct bucket_t * endMarker(struct bucket_t *b, uint32_t cap);
bucket_t *cache_t::endMarker(struct bucket_t *b, uint32_t cap)
{
// bytesForCapacity() chooses whether the end marker is inline or not
// 先根据容量计算缓存占用的内存大小
// 再计算缓存指针内存地址加上占用的大小
// 最后 -1 就是缓存在内存中的结束地址
return (bucket_t *)((uintptr_t)b + bytesForCapacity(cap)) - 1;
}
reallocate
重新生成缓存
void reallocate(mask_t oldCapacity, mask_t newCapacity, bool freeOld);
ALWAYS_INLINE
void cache_t::reallocate(mask_t oldCapacity, mask_t newCapacity, bool freeOld)
{
// 保存当前缓存容器
bucket_t *oldBuckets = buckets();
// 根据容量生成一个新缓存容器
bucket_t *newBuckets = allocateBuckets(newCapacity);
// Cache's old contents are not propagated.
// This is thought to save cache memory at the cost of extra cache fills.
// fixme re-measure this
ASSERT(newCapacity > 0);
ASSERT((uintptr_t)(mask_t)(newCapacity-1) == newCapacity-1);
// 用新的缓存容器和容量重置当前缓存
setBucketsAndMask(newBuckets, newCapacity - 1);
// 如果需要释放老缓存
if (freeOld) {
// 把老缓存添加到 garbage_refs 表中,以便稍后释放
cache_collect_free(oldBuckets, oldCapacity);
}
}
insert
保存发送消息到缓存中
void insert(Class cls, SEL sel, IMP imp, id receiver);
ALWAYS_INLINE
void cache_t::insert(Class cls, SEL sel, IMP imp, id receiver)
{
#if CONFIG_USE_CACHE_LOCK
cacheUpdateLock.assertLocked();
#else
runtimeLock.assertLocked();
#endif
ASSERT(sel != 0 && cls->isInitialized());
// Use the cache as-is if it is less than 3/4 full
// 缓存占用量 +1
mask_t newOccupied = occupied() + 1;
// 获取老的缓存容量
unsigned oldCapacity = capacity(), capacity = oldCapacity;
if (slowpath(isConstantEmptyCache())) {
// 如果当前缓存为空
// Cache is read-only. Replace it.
// 如果老容量也是空的,那么容量就设置为 4
if (!capacity) capacity = INIT_CACHE_SIZE;
// 调用 reallocate 函数重新生成容量为 4 的缓存
reallocate(oldCapacity, capacity, /* freeOld */false);
}
else if (fastpath(newOccupied <= capacity / 4 * 3)) {
// 如果新缓存占用量不足总容量的 3/4,就不作处理
// Cache is less than 3/4 full. Use it as-is.
}
else {
// 如果新缓存占用量超过了总容量的 3/4
// 如果老容量为空的,那么容量就设置为 4;否则,新容量扩充为之前的两倍
capacity = capacity ? capacity * 2 : INIT_CACHE_SIZE;
// 总容量大小不能超过 65536(即 2 的 256 次方)
if (capacity > MAX_CACHE_SIZE) {
capacity = MAX_CACHE_SIZE;
}
// 调用 reallocate 函数重新生成容量为 65536 的缓存
reallocate(oldCapacity, capacity, true);
}
// 获取缓存
bucket_t *b = buckets();
// 获取容量
mask_t m = capacity - 1;
// 根据方法名和容量生成一个哈希值
mask_t begin = cache_hash(sel, m);
mask_t i = begin;
// Scan for the first unused slot and insert there.
// There is guaranteed to be an empty slot because the
// minimum size is 4 and we resized at 3/4 full.
// 开始遍历,直到找到一个空的卡槽将消息相关数据插入
do {
// 如果缓存中哈希值 i 对应的是一个空的卡槽
if (fastpath(b[i].sel() == 0)) {
// 当前缓存使用量 +1
incrementOccupied();
// 将消息相关数据插入到哈希值 i 对应的位置
b[i].set<Atomic, Encoded>(sel, imp, cls);
// 跳出循环,并直接返回
return;
}
// 如果缓存中哈希值 i 对应的卡槽已经保存了该方法
if (b[i].sel() == sel) {
// The entry was added to the cache by some other thread
// before we grabbed the cacheUpdateLock.
// 也是跳出循环,并直接返回
return;
}
// 如果哈希值 i 对应的卡槽已经保存了其他方法,就查看哈希值(i + 1)对应的卡槽
} while (fastpath((i = cache_next(i, m)) != begin));
// 如果遍历完整个缓存的容量的每一个位置,都没能将方法插进去
// 就调用 bad_cache 函数打印日志,说明这个缓存有问题
cache_t::bad_cache(receiver, (SEL)sel, cls);
}
bucket_t
modifierForSEL
获取方法签名修饰符
uintptr_t modifierForSEL(SEL newSel, Class cls) const {
// 将方法实现的地址、方法名地址和类地址进行位异或后返回
return (uintptr_t)&_imp ^ (uintptr_t)newSel ^ (uintptr_t)cls;
}
encodeImp
对方法实现进行编码
uintptr_t encodeImp(IMP newImp, SEL newSel, Class cls) const {
// 如果没有方法实现直接返回零
if (!newImp) return 0;
// 将方法实现地址与类对象地址进行位异或运算后返回
return (uintptr_t)newImp ^ (uintptr_t)cls;
}
sel
从 bucket_t 容器中获取方法名
// 调用元素 _sel 的 load 函数获取
inline SEL sel() const { return _sel.load(memory_order::memory_order_relaxed); }
imp
从 bucket_t 容器中获取方法实现
inline IMP imp(Class cls) const {
// 调用元素 _imp 的 load 函数获取
uintptr_t imp = _imp.load(memory_order::memory_order_relaxed);
// 如果没有获取到返回空
if (!imp) return nil;
// 将获取到的值与类对象的地址进行位异或运算后返回
return (IMP)(imp ^ (uintptr_t)cls);
}
set
向 bucket_t 容器中赋值
template <Atomicity, IMPEncoding>
void set(SEL newSel, IMP newImp, Class cls);
template<Atomicity atomicity, IMPEncoding impEncoding>
void bucket_t::set(SEL newSel, IMP newImp, Class cls)
{
ASSERT(_sel.load(memory_order::memory_order_relaxed) == 0 ||
_sel.load(memory_order::memory_order_relaxed) == newSel);
// 是否需要编码方法实现
// 如果需要就调用 encodeImp 函数编码,否则就直接返回方法实现地址
uintptr_t newIMP = (impEncoding == Encoded
? encodeImp(newImp, newSel, cls)
: (uintptr_t)newImp);
// 是否需要原子性操作
if (atomicity == Atomic) {
// 如果需要原子操作
// 调用元素 _imp 的 store 函数保存方法实现
_imp.store(newIMP, memory_order::memory_order_relaxed);
// 调用元素 _sel 的 load 函数获取方法名
if (_sel.load(memory_order::memory_order_relaxed) != newSel) {
// 如果方法名不同,则调用元素 _sel 的 store 函数保存方法名
_sel.store(newSel, memory_order::memory_order_release);
}
} else {
// 如果不需要原子操作
// 调用元素 _imp 的 store 函数保存方法实现
_imp.store(newIMP, memory_order::memory_order_relaxed);
// 调用元素 _sel 的 store 函数保存方法名
_sel.store(newSel, memory_order::memory_order_relaxed);
}
}
class_data_bits_t
getBit
获取指定位的数据
bool getBit(uintptr_t bit) const {
// 通过位与运算获取 bits 中指定位数的数据
return bits & bit;
}
setAndClearBits
设置和清空指定位的数据
void setAndClearBits(uintptr_t set, uintptr_t clear) {
ASSERT((set & clear) == 0);
uintptr_t oldBits;
uintptr_t newBits;
// 开启循环,直到 bits 中的值被成功更新成 newBits
do {
// 原子操作获取原 bits 中的数据
oldBits = LoadExclusive(&bits);
// 先通过位或运算设置 bits 中指定位数的数据
// 再通过位取反运算获得要清空位
// 最后通过位与运算清空 bits 中指定位数的数据
newBits = (oldBits | set) & ~clear;
} while (!StoreReleaseExclusive(&bits, oldBits, newBits));
}
setBits
设置指定位的数据
void setBits(uintptr_t set) {
// 通过位或运算设置 bits 中指定位数的数据
__c11_atomic_fetch_or((_Atomic(uintptr_t) *)&bits, set, __ATOMIC_RELAXED);
}
clearBits
清空指定位的数据
void clearBits(uintptr_t clear) {
// 先通过位取反运算获得要清空位
// 再后通过位与运算清空 bits 中指定位数的数据
__c11_atomic_fetch_and((_Atomic(uintptr_t) *)&bits, ~clear, __ATOMIC_RELAXED);
}
data
获取数据中 class_rw_t 类型对象地址
class_rw_t* data() const {
// 将 bits 与掩码 FAST_DATA_MASK 进行位与运算
// 获取保存在 bits 中 class_rw_t 类型对象地址
return (class_rw_t *)(bits & FAST_DATA_MASK);
}
setData
设置数据中 class_rw_t 类型对象地址
void setData(class_rw_t *newData)
{
ASSERT(!data() || (newData->flags & (RW_REALIZING | RW_FUTURE)));
// Set during realization or construction only. No locking needed.
// Use a store-release fence because there may be concurrent
// readers of data and data's contents.
// 先将 bits 与掩码 FAST_DATA_MASK 的反码进行位与运算,清空原数据
// 再与新数据进行位或运算,保存新数据
uintptr_t newBits = (bits & ~FAST_DATA_MASK) | (uintptr_t)newData;
// 建立非原子和宽松原子访问的内存同步排序
atomic_thread_fence(memory_order_release);
// 保存新数据
bits = newBits;
}
safe_ro
获取数据中 class_ro_t 类型对象地址
const class_ro_t *safe_ro() {
// 获取数据中 class_rw_t 对象
class_rw_t *maybe_rw = data();
if (maybe_rw->flags & RW_REALIZED) {
// 如果类已经实现
// maybe_rw is rw
// 返回 class_rw_t 对象的 ro 元素
return maybe_rw->ro;
} else {
// maybe_rw is actually ro
// 如果类没实现
// 直接返回 class_rw_t 对象
return (class_ro_t *)maybe_rw;
}
}
- 这个方法说明,如果类还没实现,通过
data()
获取到的是class_ro_t
类型的数据 - 如果类已经实现,通过
data()
获取到的是class_rw_t
类型的数据,而class_ro_t
类型的数据保存在其ro
元素中
isAnySwift
是否为 swift 类型的数据
bool isAnySwift() {
// 只要是新版 swift 类或老版 swift 类二者之一就可以
return isSwiftStable() || isSwiftLegacy();
}
isSwiftStable
是否是来自新版稳定 Swift ABI 的 Swift 类
bool isSwiftStable() {
// 根据成员 bits 中掩码 FAST_IS_SWIFT_STABLE 储存的数据判断
return getBit(FAST_IS_SWIFT_STABLE);
}
setIsSwiftStable
设置标识当前数据为自新版稳定 Swift ABI 的 Swift 类
void setIsSwiftStable() {
// 设置成员 bits 中掩码 FAST_IS_SWIFT_STABLE 的数据
// 并且清除掩码 FAST_IS_SWIFT_LEGACY 中存储的数据
setAndClearBits(FAST_IS_SWIFT_STABLE, FAST_IS_SWIFT_LEGACY);
}
isSwiftLegacy
是否是来自老版稳定 Swift ABI 的 Swift 类
bool isSwiftLegacy() {
// 根据成员 bits 中掩码 FAST_IS_SWIFT_LEGACY 储存的数据判断
return getBit(FAST_IS_SWIFT_LEGACY);
}
setIsSwiftLegacy
设置标识当前数据为自老版稳定 Swift ABI 的 Swift 类
void setIsSwiftLegacy() {
// 设置成员 bits 中掩码 FAST_IS_SWIFT_LEGACY 的数据
// 并且清除掩码 FAST_IS_SWIFT_STABLE 中存储的数据
setAndClearBits(FAST_IS_SWIFT_LEGACY, FAST_IS_SWIFT_STABLE);
}
isSwiftStable_ButAllowLegacyForNow
是否是稳定的 Swift ABI 的 Swift 类
bool isSwiftStable_ButAllowLegacyForNow() {
// 调用 isAnySwift 判断
return isAnySwift();
}
swiftMetadataInitializer
获取 swift 类元数据初始化器
_objc_swiftMetadataInitializer swiftMetadataInitializer() {
// This function is called on un-realized classes without
// holding any locks.
// Beware of races with other realizers.
// 调用 class_ro_t 的 swiftMetadataInitializer 函数获取
return safe_ro()->swiftMetadataInitializer();
}
class_rw_t
setFlags
设置指定标志位数据
void setFlags(uint32_t set)
{
// 原子性的设置成员 flags 中指定位的数据
__c11_atomic_fetch_or((_Atomic(uint32_t) *)&flags, set, __ATOMIC_RELAXED);
}
clearFlags
清空指定标志位数据
void clearFlags(uint32_t clear) {
// 原子性的清空成员 flags 中指定位的数据
__c11_atomic_fetch_and((_Atomic(uint32_t) *)&flags, ~clear, __ATOMIC_RELAXED);
}
changeFlags
设置并清空指定标志位数据
void changeFlags(uint32_t set, uint32_t clear) {
// 要设置和要清空的不能为相同的位
ASSERT((set & clear) == 0);
uint32_t oldf, newf;
// 开启循环,直到 flags 中的值被成功更新为 newf
do {
oldf = flags;
// 先通过位或运算设置 oldf 中指定位数的数据
// 再通过位取反运算获得要清空位
// 最后通过位与运算清空 oldf 中指定位数的数据
newf = (oldf | set) & ~clear;
} while (!OSAtomicCompareAndSwap32Barrier(oldf, newf, (volatile int32_t *)&flags));
}
class_ro_t
swiftMetadataInitializer
获取 swift 类元数据初始化器
_objc_swiftMetadataInitializer __ptrauth_objc_method_list_imp _swiftMetadataInitializer_NEVER_USE[0];
_objc_swiftMetadataInitializer swiftMetadataInitializer() const {
if (flags & RO_HAS_SWIFT_INITIALIZER) {
// 如果设置了 RO_HAS_SWIFT_INITIALIZER 掩码位的数据
// 返回 _objc_swiftMetadataInitializer 类型的函数指针
return _swiftMetadataInitializer_NEVER_USE[0];
} else {
// 否则返回空
return nil;
}
}
baseMethods
获取编译时产生的方法列表
method_list_t *baseMethods() const {
// 直接返回成员 baseMethodList
return baseMethodList;
}
duplicate
复制当前 ro 数据
class_ro_t *duplicate() const {
if (flags & RO_HAS_SWIFT_INITIALIZER) {
// 如果类具有用于 swift 元数据初始化程序回调的 ro 字段
// 内存大小是当前数据占用大小 + _objc_swiftMetadataInitializer 类型的函数指针大小
size_t size = sizeof(*this) + sizeof(_swiftMetadataInitializer_NEVER_USE[0]);
// 申请内存保存当前数据的副本
class_ro_t *ro = (class_ro_t *)memdup(this, size);
// 设置副本的 swift 类元数据初始化器
ro->_swiftMetadataInitializer_NEVER_USE[0] = this->_swiftMetadataInitializer_NEVER_USE[0];
// 返回副本
return ro;
} else {
// 否则
// 内存大小就是当前 ro 数据的大小
size_t size = sizeof(*this);
// 申请内存保存当前数据的副本
class_ro_t *ro = (class_ro_t *)memdup(this, size);
// 返回副本
return ro;
}
}
category_t
methodsForMeta
获取类方法或者实例方法
method_list_t *methodsForMeta(bool isMeta) {
// 如果要获取类方法,返回成员 classMethods 中的数据
if (isMeta) return classMethods;
// 如果要获取实例方法,返回成员 instanceMethods 的数据
else return instanceMethods;
}
propertiesForMeta
获取类属性或者实例属性
property_list_t *propertiesForMeta(bool isMeta, struct header_info *hi);
property_list_t * category_t::propertiesForMeta(bool isMeta, struct header_info *hi) {
// 如果要获取实例属性,返回成员 instanceProperties 中的数据
if (!isMeta) return instanceProperties;
// 如果要获取类属性,先通过头信息 hi 判断是否类属性,如果有的话,返回成员 _classProperties 中的数据
else if (hi->info()->hasCategoryClassProperties()) return _classProperties;
// 否则就是没有类属性
else return nil;
}
protocolsForMeta
获取类协议或者实例协议
protocol_list_t *protocolsForMeta(bool isMeta) {
// 没有类协议
if (isMeta) return nullptr;
// 如果要获取实例协议,返回成员 protocols 中的数据
else return protocols;
}
今天的文章Objective-C 之 Runtime 类分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/18256.html