+initialize 懒初始化与并发状态机
objc4 runtime 懒初始化 并发等待 fork safety +initialize 懒初始化与并发状态机 +initialize 是 Objective-C 运行时在类第一次被真正使用时触发的类级初始化钩子。 objc4 的实现重点不是“调用一个方法”,而是用每个类的递归初始化锁、元类上的状态位、线程本地的初始化列表和 fork 子进程保护规则,保证父类优先、单线程执行、并发可等待、重入不死锁。 目录 作用 实现原理 核心状态字段 入口与触发 并发状态机 关键流程 测试依据 作用 +initialize 的语义是:在某个类或其子类第一次收到会触发初始化的消息前,运行时先给该类发送一次 +initialize。 这让类可以延迟建立全局状态、注册方法、准备缓存或执行只依赖本类的初始化逻辑。 懒触发 objc_getClass() 只查找类,不触发初始化;普通消息发送、部分运行时查询、autorelease 返回值路径和弱引用相关路径可能需要先完成初始化。 父类优先 子类开始初始化前,运行时递归确保父类已经初始化,避免类层次中间被并发线程插入造成死锁。 一次完成 同一类只有一个线程真正发送 +initialize;其他线程要么等待,要么在同一初始化线程重入时直接放行。 实现原理 objc4 把 +initialize 做成一个按需进入的并发状态机:消息查找路径发现目标类未初始化时,先把类 realize,再释放 runtimeLock,进入 initializeNonMetaClass()。 后者用父类递归、每类递归锁、元类状态位和线程本地初始化列表协调所有线程。真正执行用户代码的线程设置 INITIALIZING,发送 +initialize,最后在 @finally 中切换到 INITIALIZED;其他线程通过同一把类锁等待状态稳定。 这个设计的核心约束是单调性:类状态只从“未初始化”前进到“初始化中”,再前进到“已初始化”。即使 +initialize 抛异常,状态机也会完成收尾;即使发生重入,只有当前初始化线程能绕过等待;即使 fork 发生在多线程初始化期间,子进程也只允许 trivial 初始化继续,其他自定义初始化会主动终止。 核心类/结构状态字段 初始化状态存在类对象的元类标志位里。源码注释明确约束:初始时 RW_INITIALIZING 和 RW_INITIALIZED 都未设置;初始化中只设置前者;完成后清除前者并设置后者;两者永不同时为真,且 RW_INITIALIZED 一旦设置就不会清除。 ...