iOS 底层探索篇 ——类的加载原理(上)
1. objc_init 做了什么
上文说到了objc_init
调用了_dyld_objc_notify_register
,初始化了dyld 里面的sNotifyObjCMapped
,sNotifyObjCInit
,sNotifyObjCUnmapped
函数并对 sNotifyObjCMapped
,sNotifyObjCInit
直接进行了调用,那么objc_init还做了什么呢?
1.1 environ_init
首先看到environ_init
,这里面主要做了环境变量的初始化。那么环境变量有什么用呢?先把环境变量打印出来。
然后运行,发现有很多的环境变量,其中有OBJC_DISABLE_NONPOINTER_ISA
和OBJC_PRINT_LOAD_METHODS
。
NONPOINTER_ISA
就是不纯净的isa,里面不仅包含了类的信息,还有其他的一些信息
。把 OBJC_DISABLE_NONPOINTER_ISA
设为YES
,那么就不会有NONPOINTER_ISA,就会得到一个纯净的只包含类的信息的isa。
这个是没有将OBJC_DISABLE_NONPOINTER_ISA设为true之前的isa,可以看到里面包含有其他的信息,因为类信息在x86_64架构里是只有44位的,而这里不止44位有值。并且直接po isa 是得不到类的信息的。
点开editScheme
,然后在Arguments
里面的Environment variables
添加OBJC_DISABLE_NONPOINTER_ISA并设为YES。打勾后运行,可以看到这里是只占用中间一些,最后一位不为1。而且直接po isa 可以得到类的信息。
OBJC_PRINT_LOAD_METHODS
就是会把调用