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

背景描述:使用 Objective-C 开发 iOS 或者 MacOS 应用

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

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

  1. C 全局变量

    • 这些变量在程序加载时分配内存并初始化,生命周期与程序运行时一致。
  2. C 静态全局变量

    • 这些变量与普通全局变量类似,但它们仅在声明它们的文件中可见。
  3. C++ 全局变量

    • 这些变量在程序加载时分配内存,并调用其构造函数进行初始化。
  4. C++ 静态全局变量

    • 类似于 C++ 全局变量,但它们仅在声明它们的文件中可见,并在程序加载时调用其构造函数进行初始化。
  5. Objective-C 全局变量

    • 这些变量在程序加载时分配内存并初始化,生命周期与程序运行时一致。
  6. Objective-C 静态全局变量

    • 类似于 C 静态全局变量,但用于 Objective-C 类型。

初始化顺序

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

  1. 调用用 attribute((constructor)) 修饰的函数

    • 这些函数首先被调用,进行早期的初始化操作。
  2. 执行类和 Category 的 +load 方法

    • 接下来,Objective-C 运行时会执行所有类和 Category 的 +load 方法。
  3. 初始化全局变量

    • 最后,初始化各种全局变量。这包括:
      • 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. 加载可执行文件和动态链接库

    • 首先加载可执行文件和所有动态链接库,并进行重定位和符号绑定。
  2. 调用 attribute((constructor)) 修饰的函数

    • 这些函数在动态库加载后立即被调用,执行早期的初始化操作。
  3. 执行 Objective-C 类和 Category 的 +load 方法

    • 在调用 main() 之前,Objective-C 运行时会调用所有类和 Category 的 +load 方法,进行类级别的初始化。
  4. 初始化全局变量

    • 在这一步,所有全局变量(包括静态全局变量)都会被初始化。具体来说,包括:
      • C 全局变量和静态全局变量:按照它们在代码中的定义顺序初始化。
      • C++ 全局变量和静态全局变量:在加载时调用它们的构造函数进行初始化。
      • Objective-C 全局变量和静态全局变量:按照定义顺序进行初始化。

特殊情况

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

  1. 懒加载的变量

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

    • 某些动态库可能在 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
  • 27
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

依旧风轻

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值