问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

main()函数执行前,具体会初始化和创建哪些全局变量?

创作时间:
作者:
@小白创作中心

main()函数执行前,具体会初始化和创建哪些全局变量?

引用
CSDN
1.
https://blog.csdn.net/qfeung/article/details/139788406

在iOS应用开发中,了解main()函数执行前的全局变量初始化过程对于优化应用启动性能和确保程序稳定性至关重要。本文将详细介绍在iOS应用启动过程中,main()函数执行前会初始化和创建哪些全局变量,以及它们的初始化顺序。

具体会初始化和创建哪些全局变量?

在iOS应用程序的启动过程中,初始化和创建全局变量的步骤确实包含了多种类型的全局变量。具体来说,包含以下几种类型:

  1. C全局变量
  • 这些变量在程序加载时分配内存并初始化,生命周期与程序运行时一致。
  1. C静态全局变量
  • 这些变量与普通全局变量类似,但它们仅在声明它们的文件中可见。
  1. C++全局变量
  • 这些变量在程序加载时分配内存,并调用其构造函数进行初始化。
  1. C++静态全局变量
  • 类似于C++全局变量,但它们仅在声明它们的文件中可见,并在程序加载时调用其构造函数进行初始化。
  1. Objective-C全局变量
  • 这些变量在程序加载时分配内存并初始化,生命周期与程序运行时一致。
  1. Objective-C静态全局变量
  • 类似于C静态全局变量,但用于Objective-C类型。

初始化顺序

初始化的顺序依赖于编译器和链接器的实现,但通常遵循以下顺序:

  1. 调用用attribute((constructor))修饰的函数
  • 这些函数首先被调用,进行早期的初始化操作。
  1. 执行类和Category的+load方法
  • 接下来,Objective-C运行时会执行所有类和Category的+load方法。
  1. 初始化全局变量
  • 最后,初始化各种全局变量。这包括:
  • C和C++全局变量:按定义顺序初始化。
  • C和C++静态全局变量:按定义顺序初始化,但仅在声明文件中可见。
  • Objective-C全局变量:与普通全局变量类似,按定义顺序初始化。
  • Objective-C静态全局变量:按定义顺序初始化,但仅在声明文件中可见。

示例

// C全局变量
int global_c_variable = 10;
// C静态全局变量
static int static_global_c_variable = 20;
// C++全局变量
class MyClass {
public:
    MyClass() { /* 构造函数代码 */ }
};
MyClass global_cpp_variable;
// C++静态全局变量
static MyClass static_global_cpp_variable;
// Objective-C全局变量
NSString *global_objc_variable = @"Hello";
// Objective-C静态全局变量
static NSString *static_global_objc_variable = @"World";

这些全局变量会在程序启动时依次初始化,确保它们在main()函数执行前已经准备就绪。这种初始化顺序和机制确保了应用程序在启动时的稳定性和一致性。

所有全局变量都是在main()函数执行前, 初始化和创建的么?

在iOS应用程序中,绝大多数全局变量确实都是在main()函数执行之前初始化和创建的。这包括C、C++和Objective-C的全局变量和静态全局变量。这是因为在程序启动过程中,系统会先进行各种加载和初始化操作,以确保在main()函数开始执行时,所有需要的资源和状态都已经准备就绪。

全局变量初始化的顺序

  1. 加载可执行文件和动态链接库
  • 首先加载可执行文件和所有动态链接库,并进行重定位和符号绑定。
  1. 调用attribute((constructor))修饰的函数
  • 这些函数在动态库加载后立即被调用,执行早期的初始化操作。
  1. 执行Objective-C类和Category的+load方法
  • 在调用main()之前,Objective-C运行时会调用所有类和Category的+load方法,进行类级别的初始化。
  1. 初始化全局变量
  • 在这一步,所有全局变量(包括静态全局变量)都会被初始化。具体来说,包括:
  • C全局变量和静态全局变量:按照它们在代码中的定义顺序初始化。
  • C++全局变量和静态全局变量:在加载时调用它们的构造函数进行初始化。
  • Objective-C全局变量和静态全局变量:按照定义顺序进行初始化。

特殊情况

虽然上述流程适用于绝大多数情况,但在某些特定场景下,可能会有一些例外:

  1. 懒加载的变量
  • 某些全局变量可能会被设计为懒加载,即在第一次访问时才进行初始化。这种模式通常用于优化启动性能,减少不必要的初始化开销。
  1. 动态加载的库
  • 某些动态库可能在main()执行之后才会被动态加载和初始化(例如使用dlopen动态加载库)。

例子

以下是一个包含各种全局变量的示例:

// C全局变量
int global_c_variable = 10;
// C静态全局变量
static int static_global_c_variable = 20;
// C++全局变量
class MyClass {
public:
    MyClass() { /* 构造函数代码 */ }
};
MyClass global_cpp_variable;
// C++静态全局变量
static MyClass static_global_cpp_variable;
// Objective-C全局变量
NSString *global_objc_variable = @"Hello";
// Objective-C静态全局变量
static NSString *static_global_objc_variable = @"World";
// attribute((constructor))修饰的函数
__attribute__((constructor))
void early_initialization() {
    // 早期初始化代码
}
// main函数
int main(int argc, char * argv[]) {
    @autoreleasepool {
        // 程序的主要逻辑
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}

在这个示例中,所有的全局变量都会在main()函数执行之前进行初始化。early_initialization函数会在全局变量初始化之前被调用,用于执行一些早期的初始化逻辑。

总之,大部分全局变量都是在main()函数执行之前初始化和创建的,以确保程序在启动时拥有正确的运行环境。

其它的情况,也会在main()函数执行前,初始化和创建

下文中变量的定义可能与上方冲突,但这不重要,关注具体的示例就行

在Objective-C开发的iOS应用中,冷启动时在main()函数执行前,系统会创建和初始化以下类型的变量:

1. C静态全局变量

定义:在C语言中声明为static的全局变量。

链接范围:具有内部链接,只在声明它的翻译单元内可见。

生命周期:在程序开始时初始化,并在程序结束时销毁。

示例

// MyGlobal.c
#include <stdio.h>
static int myStaticGlobalVariable = 42; // 仅在MyGlobal.c内可见
__attribute__((constructor))
static void initializeMyGlobal() {
    printf("Initializing C static global variable\n");
}

2. C全局变量

定义:在C语言中未声明为static的全局变量。

链接范围:具有外部链接,可以在多个翻译单元中被引用(通过extern声明)。

生命周期:在程序开始时初始化,并在程序结束时销毁。

示例

// MyGlobal.h
extern int myGlobalVariable;
// MyGlobal.c
#include "MyGlobal.h"
int myGlobalVariable = 42;
__attribute__((constructor))
void initializeMyGlobal() {
    printf("Initializing C global variable\n");
}

3. C++静态全局变量

定义:在C++中声明为static的全局变量。

链接范围:具有内部链接,只在声明它的翻译单元内可见。

生命周期:在程序开始时初始化,并在程序结束时销毁。其初始化顺序在同一个翻译单元内是定义的,但跨翻译单元的初始化顺序是未定义的。

示例

// MyGlobal.cpp
#include <iostream>
static int myCppStaticGlobalVariable = 42; // 仅在MyGlobal.cpp内可见
__attribute__((constructor))
static void initializeMyGlobal() {
    std::cout << "Initializing C++ static global variable\n";
}

4. C++全局变量

定义:在C++中未声明为static的全局变量。

链接范围:具有外部链接,可以在多个翻译单元中被引用(通过extern声明)。

生命周期:在程序开始时初始化,并在程序结束时销毁。

示例

// MyGlobal.h
extern int myCppGlobalVariable;
// MyGlobal.cpp
#include "MyGlobal.h"
int myCppGlobalVariable = 42;
__attribute__((constructor))
void initializeMyGlobal() {
    std::cout << "Initializing C++ global variable\n";
}

5. Objective-C静态全局变量

定义:在Objective-C文件中声明为static的全局变量。

链接范围:具有内部链接,只在声明它的翻译单元内可见。

生命周期:在程序开始时初始化,并在程序结束时销毁。

示例

// MyGlobal.m
#import <Foundation/Foundation.h>
static int myObjCStaticGlobalVariable = 42; // 仅在MyGlobal.m内可见
__attribute__((constructor))
static void initializeMyGlobal() {
    NSLog(@"Initializing Objective-C static global variable");
}

6. Objective-C类静态变量

定义:在Objective-C类中声明的静态变量。

链接范围:具有内部链接,只在声明它的类内可见。

生命周期:在程序开始时初始化,并在程序结束时销毁。

示例

// MyClass.h
#import <Foundation/Foundation.h>
@interface MyClass : NSObject
+ (void)printStaticVariable;
@end
// MyClass.m
#import "MyClass.h"
@implementation MyClass
static int myClassStaticVariable = 42;
+ (void)printStaticVariable {
    NSLog(@"Class static variable: %d", myClassStaticVariable);
}
@end

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号