_objc_init
environ_init 环境变量初始化
for (size_t i = 0; i < sizeof(Settings)/sizeof(Settings[0]); i++) {
const option_t *opt = &Settings[i];
_objc_inform("%s: %s", opt->env, opt->help);
_objc_inform("%s is set", opt->env);
}
打印如下
OBJC_DISABLE_NONPOINTER_ISA 是什么呢?
设置环境变量
设置环境变量
static_init jump 全部静态C++函数调用
getLibobjcInitializers jump
runtime_init jump
UnattachedCategories jump 独立类别 表
static UnattachedCategories unattachedCategories;
allocatedClasses jump 分配的类 表
init
exception_init 异常抛出
installUncaughtSignalExceptionHandler
数组越界 工程没有崩溃 拦截到了异常
//重点代码 指针传递 能够同步发生变化 类似于指针拷贝
_dyld_objc_notify_register(&map_images, load_images, unmap_image);
map_images jump
map_images_nolock jump
未完待续...
_read_images 重点
initializeTaggedPointerObfuscator 初始化标记指针模糊器 (混淆)
//重点代码
// namedClasses
// Preoptimized classes don't go in this table.
// 4/3 is NXMapTable's load factor
//总容积 : 8 * 4 / 3
//NXCreateMapTable表 add: x = 8 * 4 / 3 * 3 / 4
int namedClassesSize = (isPreoptimized() ? unoptimizedTotalClasses : totalClasses) * 4 / 3;
gdb_objc_realized_classes = NXCreateMapTable(NXStrValueMapPrototype,namedClassesSize); //NXCreateMapTable 创建表
ts.log("IMAGE TIMES: first time tasks");
gdb_objc_realized_classes 表
//另外的表
objc::unattachedCategories.init(32);
objc::allocatedClasses.init();
gdb_objc_realized_classes、allocatedClasses这俩表有什么区别呢?
gdb_objc_realized_classes 总表 不管实现与否,可以是没被开辟过的
allocatedClasses 总表 已经被开辟过的
_read_images 下断点
输出
sel_registerNameNoLock jump
__sel_registerName jump
search_builtins jump _dyld_get_objc_selector
_read_images-resolvedFutureClasses 已解析的未来类
在加载的过程中,有的类在读取之后就会被删除掉,但是删除没有删干净,就会出现一些混乱(野指针),也就是残留的类。
po 打印
_getObjc2ClassRefs jump
readClass
//重点代码
class_rw_t *rw = newCls->data();
const class_ro_t *old_ro = rw->ro();
memcpy(newCls, cls, sizeof(objc_class));
// Manually set address-discriminated ptrauthed fields
// so that newCls gets the correct signatures.
newCls->setSuperclass(cls->getSuperclass());
newCls->initIsa(cls->getIsa());
rw->set_ro((class_ro_t *)newCls->data());
newCls->setData(rw);
freeIfMutable((char *)old_ro->getName());
free((void *)old_ro);
addRemappedClass(cls, newCls);
输出
加入判断条件
控制台只输出 readClass - HL - HLPerson
addNamedClass jump
addClassTableEntry jump
待续...
addNamedClass 里调用 NXMapInsert jump
_read_images
//重点代码
for (i = 0; i < count; i++) {
Class cls = (Class)classlist[i];
//初识这个地址->名字->类
Class newCls = readClass(cls, headerIsBundle, headerIsPreoptimized);
//进行试探
if (newCls != cls && newCls) {
// Class was moved but not deleted. Currently this occurs
// only when the new class resolved a future class.
// Non-lazily realize the class below.
resolvedFutureClasses = (Class *)
realloc(resolvedFutureClasses,
(resolvedFutureClassCount+1) * sizeof(Class));
resolvedFutureClasses[resolvedFutureClassCount++] = newCls;
}
}
接下来进行试探
1
// Realize non-lazy classes (for +load methods and static instances)
for (EACH_HEADER) {
classref_t const *classlist = hi->nlclslist(&count);
for (i = 0; i < count; i++) {
Class cls = remapClass(classlist[i]);
if (!cls) continue;
//HL
const char *mangledName = cls->nonlazyMangledName();
const char *HLPersonName = "HLPerson";
if (strcmp(mangledName, HLPersonName) == 0) {
printf("Realize non-lazy-%s - HL - %s\n",__func__,mangledName);
}
//HL
2
if (resolvedFutureClasses) {
for (i = 0; i < resolvedFutureClassCount; i++) {
Class cls = resolvedFutureClasses[i];
//HL
const char *mangledName = cls->nonlazyMangledName();
const char *HLPersonName = "HLPerson";
if (strcmp(mangledName, HLPersonName) == 0) {
printf("resolvedFutureClasses-%s - HL - %s\n",__func__,mangledName);
}
//HL
上面两个判断都没进
realizeClassWithoutSwift 核心重点
//rw赋值 (ro 赋值给 -> rw)
rw = objc::zalloc<class_rw_t>();
rw->set_ro(ro);
rw->flags = RW_REALIZED|RW_REALIZING|isMeta;
cls->setData(rw);
setInstancesRequireRawIsa //集合实例需要原始Isa
DisableNonpointerIsa //环境变量
继承链 isa走位
supercls = realizeClassWithoutSwift(remapClass(cls->getSuperclass()), nil);
metacls = realizeClassWithoutSwift(remapClass(cls->ISA()), nil);
添加判断
没有打印出*$2的地址
打印
prepareMethodLists jump
prepareMethodLists方法里fixupMethodList jump
meth.name jump
打印ro 未打印出*$2的值
rwe 什么时候赋值呢?
realizeAndInitializeIfNeeded_locked jump
realizeClassMaybeSwiftMaybeRelock jump
验证了只要是消息发送的时候类方法和实例方法 所属类对象都可以进行加载
懒加载类情况 数据加载推迟到第一次消息的时候
lookUpImpOrForward
realizeClassMaybeSwiftMaybeRelock
realizeClassWithoutSwift
methodizeClass
非懒加载类情况 map_images 的时候加载所有类数据
redClass
_getObjc2NonlazyClassList
realizeClassWithoutSwift
methodizeClass
分类是怎么加载的?怎么调用的?
attachToClass
methodizeClass
// Install methods and properties that the class implements itself.
method_list_t *list = ro->baseMethods();
if (list) {
prepareMethodLists(cls, &list, 1, YES, isBundleClass(cls), nullptr);
if (rwe) rwe->methods.attachLists(&list, 1);
}
auto rwe = rw->ext();
txt jump
class_rw_ext_t *ext() const {
return get_ro_or_rwe().dyn_cast<class_rw_ext_t *>(&ro_or_rw_ext);
}
class_rw_ext_t *extAllocIfNeeded() {
auto v = get_ro_or_rwe();
if (fastpath(v.is<class_rw_ext_t *>())) {
return v.get<class_rw_ext_t *>(&ro_or_rw_ext);
} else {
return extAlloc(v.get<const class_ro_t *>(&ro_or_rw_ext));
}
}
extAllocIfNeeded jump
1、attachCategories 添加分类时 调用
2、class_setVersion设置类版本时
3、addMethods_finish 添加方法完成时
4、class_addProtocol 类添加协议
5、_class_addProperty
6、objc_duplicateClass
分类什么时候加载的?
attachCategories调用 重点
1、attachToClass
2、load_categories_nolock
提出一个疑问为什么要有rwe、rw、ro?三者之间又是怎么样的联系?
ro clear m沙河路径加载过来的 readonly
ro 复制一份寸在rw
rw 脏内存
运行时功能
1、添加分类、添加的方法
2、api addMethods
ro 是readonly 不能修改,所以就得用rw
但是并不是每个类都会用到分类,就会产生脏内存,这时候就用到了rwe。
类里面 有方法 协议 属性 名字 父类
read_image clas->data
auto ro = (const class_ro_t *)cls->data();
打印出 realizeClassWithoutSwift - realizeClassWithoutSwift - HL - HLPerson
class_getClassMethod jump
根据格式还原
auto ro = (const class_ro_t *)cls->data();
自动去找到当前的类型,进行挨个赋值,除非当前的格式地址不匹配无法解析,所以ro从Mach-O里面读到地址指针,可以对class_ro_t的所有相应数据进行赋值。
rwe赋值
extAllocIfNeeded
attachCategories
methodizeClass方法里3次调用attachToClass
methodizeClass - previously = nil
realizeClassWithoutSwift - previously
attachLists
观察分类是否已经到主类里面来了
打印完21个方法,还是没有看到分类的方法
通过观察发现(method_list_t *) $0 = 0x00007fff80ad89c8 与 [63] = 0x00007fff80ad89c8 是一致的
p mlists + ATTACH_BUFSIZ - mcount
p addedLists
两个值是一样的
总结
1: 两个都有 load方法 : _read_images 非赖加载类 - realizeClassWithoutSwift - load_categories_nolock - attachCategories
2: 分类 load + 主类没有 ( data()里面获取 ) _read_images - realizeClassWithoutSwift - methodizeClass - attachToClass - 没有走 attachCategories
3: 分类 没有 + 主类 load ( data() ) _read_images - realizeClassWithoutSwift - methodizeClass - attachToClass - 没有走 attachCategories
4: 两个都没有 main 什么都没有 -> 推迟到 第一次消息发送的时候 初始化 -> data()
5: 两个都有 load方法 - 很多的分类 (分类不都有load)
补充
method_list_t jump
指针 指向真正的method_t
method_list_t 继承于 entsize_list_tt
method_list_t 调用 getOrEnd
//getOrEnd本类调用
Element& getOrEnd(uint32_t i) const {
ASSERT(i <= count);
return *PointerModifier::modify(*this, (Element *)((uint8_t *)this + sizeof(*this) + i*entsize()));
}
Element& get(uint32_t i) const {
ASSERT(i < count);
return getOrEnd(i);
}
prepare_load_methods 调用 realizeClassWithoutSwift / _getObjc2NonlazyCategoryList,主类realizeClassWithoutSwift被执行
![]](https://img.haomeiwen.com/i6517975/b2433701d77b8f13.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
lookUpImpOrForward 里调用了getMethodNoSuper_nolock
getMethodNoSuper_nolock jump
//重点
_object_set_associative_reference jump 对象集关联引用 用来存储
网友评论