SwiftUI App初始化监听applicationState崩溃问题排查
崩溃的直接原因
App的init()方法处于应用启动的最早期阶段,此时UIApplication.shared实例虽能被获取,但内部基于NSObject的底层结构尚未完全初始化。你代码中使用的publisher(for: \.applicationState)依赖KVO(键值观察)机制,而KVO是NSObject的核心特性,当尝试将未完成初始化的UIApplication实例转为NSObject时,就会触发空指针类型转换错误。
@MainActor解决问题的核心原因
执行时机的延迟与保障
@MainActor修饰的函数会被调度到主线程的事件循环中执行,而非在App的init()阶段同步运行。这意味着代码会被推迟到UIApplication完全初始化完成后(对应applicationDidFinishLaunching及之后的阶段)才执行,此时UIApplication的NSObject底层结构已经就绪,KVO相关逻辑能正常工作。原代码中
subscribe(on: DispatchQueue.main)的局限性
你原代码里的subscribe(on: DispatchQueue.main)仅能保证Publisher的订阅逻辑在主线程执行,但创建Publisher(即调用UIApplication.shared.publisher(for:))的代码是在App init()早期同步执行的,此时UIApplication还未完成初始化,所以无法解决核心的时机问题。而@MainActor隔离会让整个函数体的执行都推迟到合适时机,从根源上避免了未初始化的问题。
场景验证
你提到代码在applicationDidFinishLaunching之后运行正常,也印证了这一点:此时UIApplication已完成所有初始化流程,NSObject相关底层结构完全就绪,KVO Publisher可以正常工作。
内容的提问来源于stack exchange,提问作者Tometoyou

