美文网首页
你真的了解dyld么?

你真的了解dyld么?

作者: HotPotCat | 来源:发表于2021-04-29 17:28 被阅读0次

有一个工程DyldDemo依赖AB两个动态库,依赖信息如下图所示:

image.png

DyldDemo关键内容

AppDelegate.m:

+ (void)load {
    NSLog(@"AppDelegate load");
}

ViewController.m:

+ (void)load {
    NSLog(@"ViewController load");
}

ViewController+Additions.m:

+ (void)load {
    NSLog(@"ViewController Additions load");
}

AppDelegate+Additions.m:

#import "AppDelegate+Additions.h"

__attribute__((constructor)) void func3() {
    printf("\n ---func3--- \n");
}


__attribute__((constructor)) void func4() {
    printf("\n ---func4--- \n");
}


@implementation AppDelegate (Additions)

+ (void)load {
    NSLog(@"AppDelegate Additions load");
}

@end

main.m:

__attribute__((constructor)) void func1() {
    printf("\n ---func1--- \n");
}


__attribute__((constructor)) void func2() {
    printf("\n ---func2--- \n");
}

int main(int argc, char * argv[]) {
    NSString * appDelegateClassName;
    NSLog(@"---MAIN---");
    @autoreleasepool {
        // Setup code that might create autoreleased objects goes here.
        appDelegateClassName = NSStringFromClass([AppDelegate class]);
    }
    return UIApplicationMain(argc, argv, nil, appDelegateClassName);
}

A 关键内容

Compile Sources:

image.png

A1.m:

#import "A1.h"

__attribute__((constructor)) void func_A1() {
    printf("\n ---func_A1--- \n");
}

@implementation A1

+ (void)load {
    NSLog(@"A1 Load");
}

@end

A2.m:

#import "A2.h"

__attribute__((constructor)) void func_A2() {
    printf("\n ---func_A2--- \n");
}


@implementation A2

+ (void)load {
    NSLog(@"A2 Load");
}

@end

A1+Addtions.m:

#import "A1+Addtions.h"

@implementation A1 (Addtions)

+ (void)load {
    NSLog(@"A1 Addtions Load");
}

@end

B 关键内容

Compile Sources:

image.png

B1.m:

#import "B1.h"

__attribute__((constructor)) void func_B1() {
    printf("\n ---func_B1--- \n");
}

@implementation B1

+ (void)load {
    NSLog(@"B1 Load");
}

@end

B2.m:

#import "B2.h"

__attribute__((constructor)) void func_B2() {
    printf("\n ---func_B2--- \n");
}

@implementation B2

+ (void)load {
    NSLog(@"B2 Load");
}

@end

问题:程序运行到[ViewController viewDidLoad]控制台输出什么?

⚠️在Debug环境下,不考虑编译器优化。并且没有进行二进制重排。






问题分析:

  1. 首先初始化B,再初始化A,最后初始化主程序DyldDemo

根据dyld源码可知dyld初始化image list从下标1开始,最后再初始化主程序(下标0)。而image list顺序与Link Binary With Libraries顺序有关。

image.png
dyld相关源码如下:
image.png
  1. B分析
    由于B1.mB2.m前面,所以先执行B1+ load方法。所以B1的输出为:
B1 Load
B2 Load
---func_B1---
---func_B2---

根据dyld的源码可知c++的全局构造函数调用在+load方法之后。
dyld相关源码(ImageLoader::recursiveInitialization):

image.png
  1. A分析
    A中的文件顺序A1+AdditionsA2A1。所以A中的输出应该为:
A2 Load
A1 Load
A1 Addtions Load
---func_A2---
---func_A1---

根据dyldobjc源码可知,分类的+load方法加载是在所有类的+load方法加载后,c++构造函数前调用的。
objc-loadmethod.mm:

image.png
  1. DyldDemo分析
    文件顺序为main.mAppDelegate+AdditionsViewController+AdditionsViewControllerAppDelegate。根据AB的分析同理可得DyldDemo的输出为:
ViewController load
AppDelegate load
AppDelegate Additions load
ViewController Additions load
---func1---
---func2---
---func3---
---func4---
---MAIN---

+load是在objc中调用的,c++全局构造函数是在dyld中调用的,这两个调用都在main函数之前。

  1. 所以整体输出为
B1 Load
B2 Load
---func_B1---
---func_B2---
A2 Load
A1 Load
A1 Addtions Load
---func_A2---
---func_A1---
ViewController load
AppDelegate load
AppDelegate Additions load
ViewController Additions load
---func1---
---func2---
---func3---
---func4---
---MAIN---

运行代码验证:

image.png

总结

  • Dyld初始化image是按Link Binary With Libraries顺序逐个初始化的,从下标1开始,最后再初始化主程序(下标0)。可以理解为是按image进行分组的。
  • image内部是先加载所有类的+ load,再加载分类的+ load,最后加载C++全局构造函数。(类load->分类load->C++构造函数)。+loadobjc中调用的,C++全局构造函数是在dyld中调用的。(在不考虑二进制重排等的优化下,image内部的顺序默认是按Compile Sources中顺序进行的)。
  • main函数是在dyld返回入口函数(main)之后才调用的。

Demo

相关文章

  • 你真的了解dyld么?

    有一个工程DyldDemo依赖A和B两个动态库,依赖信息如下图所示: DyldDemo关键内容 AppDelega...

  • 你真的了解么?

    最近很多学弟学妹找到我,咨询一些问题,因为我也是从那个迷茫的时候过来的,所以很多问题我也面临过,忍不住想在这里分享...

  • 你真的了解么?

    红灯笼高高挂起,亲朋好友聚集,虽然桌子上鸡鸭鱼肉平时都可以吃到并不稀奇,但过年的意味还在那里,热闹的...

  • 你真的了解辟谷么

    今天备谷第五天,本来想吃点特别的,没想到一天三顿水果而且都是小番茄。 很多人觉得“辟谷”就是不吃饭,所以会有很多人...

  • 你真的了解复利么?

    2500年前,腓尼基旅行家昂蒂帕克写下了炫人眼目的七大奇迹清单:埃及吉萨金字塔、奥林匹亚宙斯巨像、阿尔忒弥斯神庙、...

  • 你真的了解时间么?

    无论在何种文化中,时间都扮演者重要的角色。农耕文化中的时间,是依自然节奏框定的,这是因为,农民的生产紧密依附于自然...

  • 国足,你真的了解么?

    2005年,偶然在电视上看到了一个身穿8号的美国人扣篮的动作,那是对于科比的第一印象,那是对于运动的第一印象...

  • 你真的了解自己么?

    自从学习了天赋密码,身边时不时就会有一些小伙伴时不时让你给算算。 的确,挺有用。为什么我会说有用,而不是说很准呢?...

  • 你真的了解白酒么

    中国白酒的历史非常久远,经过考古发现,可以追溯到9000年前的贾湖文化。中国白酒的由来有多种说法,一曰猿猴造酒;二...

  • 你真的了解投资么?

    投资 投资是要以深入分析为基础,确保本金的安全,并获得适当的回报一种行为。 投机 不满足上面这些要求的操作,就是投...

网友评论

      本文标题:你真的了解dyld么?

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