OC-类加载

2020-12-14 15:14:32 浏览数 (1)

一·Init

1.runinit

2.do init

3.init libsys

4.init dispatch

5.os_object_init

6.libobjc.A.dylid

7.main()

7.1 environ_init() //环境初始化

7.2 tls_init()

7.3 static_init()

7.4 runtime_init()

7.5 cache_init() //共享缓存

7.6 implementationwithBlock_init() //初始化block

7.7 exception_init() //捕捉crash

7.8dyld_objc_notify_register (映射map镜像,load镜像,unmap还未被映射镜像)类加载

8.sNotifyObjcinit

9.sNotifyObjcMapped

二·map & load

map 管理动态库中的符号:class名字,protocol名字,selector名字,分类category名字

map_images(objcImageCount,paths,mhs);

load_images 加载操作(image->getRealPath(),image->machHeader());

三·map_images

第一步镜像枷锁

mutex_locker_t lock(runtimeLock)

第二步读取镜像

read_image(

1.修复预编译阶段的@selector的混乱

2.修复错误混乱的class

递归 read_class{

mangleName = cls->mangleName //拿到类名

addNamedClass->GDB(NXMapInsert)表 添加类

addClassTableEntry{

添加类出口-添加类申请-初始化

allocatedClass 在runtime objc_init处初始化

}

}

}

3.修复重映射一些没有被镜像文件加载进来的类

4.修复一些消息

5.有协议readProtocol

6.修复没有被加载的协议

7.分类处理

8.类的加载处理

9.没有被处理的类,优化被invalid的类

10.realizeClassWithoutSwift //有关类的方法在上一篇类方法文章中有提及

四·流程图

可执行程序生成图可执行程序生成图

五·懒加载和非懒加载

懒加载:

lookUpImpOrForward

realizeClassMaybeSwiftMaybeRelock

懒加载的数据会推迟到第一次的消息发送objc_msgSend后

匹配分类attach categories

realizeClassWithoutSwift

methodizeClass

非懒加载

_getObjc2NonlazyClassList

readClass

map_images的时候会加载所有的类信息

匹配分类attach categories

realizeClassWithoutSwift

methodizeClass

六·分类categories

分类的结构

_category_t{ _class_t{ method_t{

char *name isa SEL name

struct _class_t *cls superclass char *types

struct _method_list_t *instance_methods cache MethodListIMP imp

struct _method_list_t *class_methods vtable }

struct _protocol_list_t *protocols ro

struct _prop_list *properties }

}

注释:分类的属性没有实现set get方法

关联到类

attachCategories{

rew->methods.attachList(mlist,size,count)

rew=cls->data()

rew后还有一步cls->data()->extAllocIfNeed() 如果你对原始缓存做出了修改会执行这一步如果你需要在分类加属性 协议 方法 会调用

attachList(mlists attach_bufsize-mcount,mcount){

//倒序插入

mlist[attach_bufsize - mcount] =mlist

从lists开始,放addList容量count ,放多大

memcpy(array()->lists,addedLists,addedCount*sizeof(array()->lists[0]));

//加入一个集合

listlist

}

其中cls->data() 是从bits.data()中读取

}

1.cls->setInstanceSize(ro->instanceSize)

x/4gx class 第四位16位地址有大小值

2.cls->setHasCxxDtor()

x/4gx class 第四位16位地址有标识值

```

非/懒加载

主类load 分类load

Nolazylist true

主类load 分类 空

read_image处加载data true

主类 空 分类 空

第一次消息处data() false

主类 空 分类 load

会强行把主类也变为load true

关联对象

objc_setAssociatedObject()

objcassoiction association{policy,value}包装策略和对象=bucket

1.创建一个或多个管理类 manager lock

AssociationsManager() lock

~AssociationsManger() unlock 注:避免多线程调用

2.获取唯一静态哈希表

AssociationHashMap &associations(manage.get())

3.判断value是否存在,并传入一个对象disguised和一个空bucket

associations.try_emplace(disguised,ObjectAssociationMap{})

传入的两个参数经过判断

3.1如果不为空LookupBucketFor(Key,TheBucket) 并创建对makeIterator(TheBucket,getEnd(),true)

用当前修饰策略和value组成的对(TheBucket)替换2.2返回的空nikbucket,并标记第一次为Map true,并返回reslut和FoundBucket,foundBucket返回给TheBucket(结果是一对基础邓氏表DenseMapBase)顺便给Thebucket一个哈希下标用于查找

getHashValue & (NumBuckets-1)

//If we found an empty bucket ,the key doesn`t exist in the set .Insert it and return the defaule value ProbeAmt =1;

LLVM_LIKE

FoundBucket = FoundTombstone ? FoundTombstone : ThisBucket

否则一直循环直到ThisBucket = FoundTombstone,既bucket的哈希下标与probeAmt的下标检索寻找对应的index

3.2如果为空插入一个新的元素InsertIntoBucket(TheBucket,Key)并创建对makeIterator(TheBucket,getEnd(),false)

如果没有Key,insert一个空的bucket并返回.插入的对象就是value和策略的包装

4.标记对象存在关联

object->setHasAssociatedObject()

isa处的has_assoc 标记为true //it`s the first association we make 如果是第一次创建设置为true

5.创建或替换associate

查看当前应用对象类型refs_reslut

如果不存在-替换swap(result.first->second)

6.如果value传进来是个空值 释放

associations.erase(refs_it)

AssociatManage

AssociateHashMap1

AssociateHashMap2

AssociateHashMap

Buckets

NumEntries

Buckets 一维结构

Disguised<objcet1>

ObjcAssociateMap1(try_emplace)

Disguised<objcet2>

ObjcAssociateMap2(try_emplace)

```

```

Disguised<objcetn>

ObjcAssociateMap2(try_emplace)

ObjcAssociateMap1

Buckets

NumEntries

Buckets 二维结构

const void * bucket1

ObjcAssociate1(try_emplace)

const void * bucket2

ObjcAssociate2(try_emplace)

```

```

const void * bucketn

ObjcAssociaten(try_emplace)

ObjcAssociation{policy,value}

0 人点赞