美文网首页
1. app启动到内存加载

1. app启动到内存加载

作者: 算命的李老师 | 来源:发表于2020-09-07 21:50 被阅读0次
==app启动到Runtime==

例子:

#import <Foundation/Foundation.h>

@interface HelloWorld : NSObject

- (void) sayHello;

@end

@implementation HelloWorld

+ (void) load {
    NSLog(@"Hello World load");
}

- (instancetype) init {
    if(self = [super init]) {
        NSLog(@"Hello World init");
        return self;
    } else
        return nil;
}

- (void) sayHello {
    NSLog(@"Hello World");
}

@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        HelloWorld* helloworld = [HelloWorld new];
        [helloworld sayHello];
    }
    return 0;
}

编译完成后,这个可执行文件,有一个头部,用于表明文件信息:

Mach header
      magic cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
MH_MAGIC_64  X86_64        ALL LIB64     EXECUTE    18       2496   NOUNDEFS DYLDLINK TWOLEVEL PIE

当你执行它,该二进制文件会被读取,操作系统可执行程序加载器会加载该文件,读取该头部,判断是否是一个合法的二进制可执行文件,如果可以执行,则开始文件的 parse (解析)过程,该过程提取 LC (Load Command) 信息。这里会找到应用程序入口信息 LC_MAIN,动态连接器加载器 LC_LOAD_DYLINKER 信息等,如果找到合法的动态连接器,则调用它,将控制权交给它,这时默认的 dyld (动态链接器)会再对二进制文件进行 parse,找到 LC_LOAD_DYLIB ,这里可能有多个。

对于一个最简单的 Cocoa App,至少会有 :
/System/Library/Frameworks/Foundation.framework/Versions/C/Foundation (offset 24)
/usr/lib/libobjc.A.dylib (offset 24) (ObjC runtime)
/usr/lib/libSystem.B.dylib (offset 24) (C runtime)
/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (offset 24)

这时 dyld 会加载或映射这些库到地址空间中来,解析符号,初始化库,在初始化的过程中,库可以向 dyld 注册回调函数,runtime 这时即可获取文件中诸如 __objc_classlist __objc_nlclslist __objc_methname 等等信息,用于构建各类关系,为 OC 特性作支撑。

最后,dyld 会找到 LC_MAIN 入口压入初始化参数等,跳转将控制权交与程序本身,这时开始运行。
运行过程中,dyld 负责动态解析符号,比如 [helloworld sayHello] 该调用实际在编译时被替换为 objc_msgSend 然而 objc_msgSend 又在 runtime 里,这样,runtime 也就会时时存在,所有的方法调用,OC 特性的使用都会到 runtime 里。

==Category 在编译过后,是在什么时机与原有的类合并到一起的?==
  • 程序启动后,通过编译之后,Runtime 会进行初始化,调用 _objc_init。
  • 然后会 map_images。
  • 接下来调用 map_images_nolock。
  • 再然后就是 read_images,这个方法会读取所有的类的相关信息。
  • 最后是调用 reMethodizeClass:,这个方法是重新方法化的意思。
  • 在 reMethodizeClass: 方法内部会调用 attachCategories: ,这个方法会传入 Class 和 Category ,会将方法列表,协议列表等与原有的类合并。最后加入到 class_rw_t 结构体

相关文章

  • 1. app启动到内存加载

    ==app启动到Runtime== 例子: 编译完成后,这个可执行文件,有一个头部,用于表明文件信息: 当你执行它...

  • iOS 性能优化相关整理(待补充)

    1. 基础优化 1. 减少使用xib及storyboard(加载速度慢;导致APP启动时间比较耗时,因为在APP启...

  • iOS开发——懒加载

    懒加载的定义 懒加载也称为延迟加载,即在需要的时候才加载(效率低,占用内存小)。iOS设备的内存有限,如果程序在启...

  • iOS 启动优化(上)

    相关概念 App 启动分类 冷启动 内存中不包含App的相关数据,必须从磁盘加载到内存(即 App 被 kill ...

  • Runtime初探---类和方法的本质

    iOS app 加载流程 由 cpu 自硬盘中提取 app 数据流 加载至 内存中 链接app运行需要的各种库 执...

  • iOS检测CPU内存占用和耗电量的方法

    一、Cpu/内存测试 选择activity monitor打开,加载好app,点击录制,操控app,停止录制,将c...

  • App启动优化

    要想优化App的启动过程,需要先了解App的启动流程。 App启动调用顺序:1:加载info.plist里设置的启...

  • 同程APP启动过程时长统计及优化方案

    同程APP启动过程时长统计及优化方案: APP启动到首页加载完:1.64s - 1.74s 一、AppDelega...

  • IOS 启动优化

    冷启动:官方解释:也就是app不在内存中,从头加载整个应用;热启动:官方解释:app已经在内存中,即从后台切换到a...

  • Android自定义View实现加载大长图

    Android加载大长图 一、为什么Android加载图片要进行压缩? Android系统为app分配的内存是有限...

网友评论

      本文标题:1. app启动到内存加载

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