一·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]));
//加入一个集合
}
其中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}