美文网首页iOS开发之深入理解runtimeRuntime源码iOS
iOS开发之runtime(9):_objc_init()了解一

iOS开发之runtime(9):_objc_init()了解一

作者: kyson老师 | 来源:发表于2018-12-23 22:59 被阅读45次

本系列博客是本人的源码阅读笔记,如果有iOS开发者在看runtime的,欢迎大家多多交流。为了方便讨论,本人新建了一个微信群(iOS技术讨论群),想要加入的,请添加本人微信:zhujinhui207407,【加我前请备注:ios 】,本人博客http://www.kyson.cn 也在不停的更新中,欢迎一起讨论

runtime logo

本文完整版详见笔者小专栏:https://xiaozhuanlan.com/runtime


背景

上一篇文章中,我们清除了Win32的相关逻辑。本篇文章将继续带大家研究_objc_init()方法,其中可能会涉及到:

  1. 清理一些与我们理解_objc_init()无帮助或者可能导致模糊的代码
  2. 介绍头文件objc-private.h

详细

之前的文章我们有说过_objc_init()方法是runtime被加载后第一个执行的方法。这个方法有如下几个函数:

void _objc_init(void)
{
    environ_init();
    tls_init();
    static_init();
    lock_init();
    exception_init();

    _dyld_objc_notify_register(&map_2_images, load_images, unmap_image);
}

其中
environ_init()方法之前的文章已经有提过
tls_init()方法这里先不多做介绍,因为涉及的知识面比较广,后面的文章会给于详细解释static_init()也非常有意思,涉及到mach-o文件的构成,这里先不做过多介绍,后面再解释
lock_init()从名字可以看出是跟锁相关
exception_init()跟异常相关
_dyld_objc_notify_register是这个方法的主角,我们点进去看他的介绍:


本文完整版详见笔者小专栏:https://xiaozhuanlan.com/runtime


意思是dyld专门为runtime设计的方法。关于dyld这里也先不多做介绍了,后面的文章会详细介绍的。

这里笔者要提醒读者的是:

我们如何找到一个方法的实现

是的,其实不论是在点击lock_init()还是点击exception_init()我们很可能点击到错误的实现里。

exception_init方法

如图,搜索结果有多个方法,但真正objc_init()调用的下图的


实际调用的exception_init方法

那么为何第一张图的exception_init方法未执行,而第二张的执行了呢,这里我们又看到了一个关键宏:

#if !__OBJC2__

按上一篇的思路,我们继续编写测试程序如下:

int main() {
    printf("__OBJC2__: %d\n",__OBJC2__);
}

运行后看到后台有如下输出:

__OBJC2__: 1
Program ended with exit code: 0

笔者没有找到官方的文档对于__OBJC2__的定义,但从字面意思来看就是判断宏内的代码是不是运行在Objective-C 2.0上的,而大部分iOS开发者都知道,我们目前使用的Objective-C 是 2.0的,因此这个宏返回的是true。

既然知道了这一点,我们可以对文件 objc-exception.mm 做一些删减:
*#if !__OBJC2__后面的代码清理掉,结果如下:

清理后的代码

推而广之,我们全局搜索#if !__OBJC2__可以做相似的操作:

搜索“OBJC2”的部分结果

其他

全局搜索_objc_init(可以发现,_objc_init()方法的定义位于文件 objc-internal.h 中:

// Initializer called by libSystem
OBJC_EXPORT void _objc_init(void)

lock_init方法位于 objc-private.h 中:

extern void lock_init(void);

同样的,还有tls_init位于 objc-private.h 中:

extern void tls_init(void);

objc-private.h 和 objc-internal.h 文件后面这两个文件大家后面会经常接触,这里先有个了解:对,这两个文件很重要。


本文完整版详见笔者小专栏:https://xiaozhuanlan.com/runtime


相关文章

网友评论

    本文标题:iOS开发之runtime(9):_objc_init()了解一

    本文链接:https://www.haomeiwen.com/subject/izeokqtx.html