您好,欢迎来到叨叨游戏网。
搜索
您的当前位置:首页iOS底层-应用程序加载

iOS底层-应用程序加载

来源:叨叨游戏网

背景

  • 我们一直在用手机玩App但App启动都做了什么呢?App启动到main函数中间都做了什么?
  • 我们一直写代码,代码又是如何写入内存中的呢?
  • 我们导入的动/静态库怎么加载到内存的?
  • objc_init怎么来的?我们前面探索了那么多objc源码它怎么启动的呢?
  • dyld到主程序main的过程做了什么?
  • dyld2 和 dyld3的区别?

准备

  • 可编译的objc4工程
  • dyld源码
  • libdispatch、libsystem源码

App加载原理

库:可执行的二进制文件能够被加载到内存中

  • 静态库:(.a/.lib) 静态链接 优点:编译速度快 缺点:包体积变大
  • 动态库:(.so/.dll/.framwork)动态链接 优点:共享相同库,优化内存空间和包大小。缺点:编译速度慢
  • 可执行文件:放在终端能够运行起来
    动静态库区别主要在链接方式不一样,以空间换时间和以时间换空间的区别,没有好与坏选择合适的方式保持动态平衡

动态链接器(dyld)

dyld流程源码分析:

我们从程序运行汇编调试看到dyld_start是dyld的方法

下面我们来分析dyld动态链接器源码程序执行过程:

dyld到主程序main过程

lldb到objc源码中的objc_init,使用bt,逆向推导 :
doinitialization-> doModInitFunctions(dyld) -> libSystem.B.dyliblibSystem_initializer:->libdispatch.dyliblibdispatch_init:->_os_object_init(libdispatch.dylib) -> _objc_init(libobjc)

  • 小节汇总-> 首先要libSystem系统库先加载,然后libdispatch线程库加载

doinitialization和context.notifySingle关系

_dyld_objc_notify_register(&map_images, load_images, unmap_image);
map_images:关联重要内容数据

然后进入_dyld_objc_notify_register:

找到setObjCNotifiers函数并进入:

里面有三个重要参数:
mapped,init,unmapped

doInitialization初始化赋值

然后赋值_dyld_objc_notify_register-> registerObjCNotifiers:


map_images 和 load_images:

map_images和load_images是dyld和objc沟通的过程

map load - map()
notifySingle : load()


objc的load_images会在dyld的registerObjCNotifiers:开始调用

dyld流程分析图示:

我们可了解dyld流程的App加载过程

总结分析

  • 感受:有时候内容不重要,分析问题和内容的能力很重要
  • 通过符号断点dyld3是iOS使用的框架(WWDC2017)
  • 我们通过探索发现objc_init做程序初始化,而且里面有很多函数初始化,那它里面都做了什么?若感兴趣请移步:

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- gamedaodao.net 版权所有 湘ICP备2024080961号-6

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务