iOS 15 Beta版首屏ViewController viewDidLoad中keyWindow为nil问题求助
iOS 15 Beta 首屏 viewDidLoad 阶段 keyWindow 为 nil 问题解决方案
问题共性说明
该问题是iOS 15 早期Beta版本(版本号19A5337a)的已知时序异常,大量未接入UISceneDelegate、仍使用UIApplicationDelegate管理生命周期的项目都遇到了相同问题,iOS 14及更低版本不受影响。
可行修复方案
临时适配方案
如果仅需要在Beta测试阶段规避问题,后续iOS 15正式版发布后会调整兼容逻辑,可以将获取keyWindow的逻辑从viewDidLoad延后到viewDidAppear:阶段执行,该阶段UIWindow已经完成挂载,可以正常获取到有效值,注意添加执行标记避免逻辑重复触发即可。
永久兼容方案
如果需要长期兼容多版本系统,建议替换原有UIApplication.shared.keyWindow的调用方式,改为主动筛选有效window,兼容代码如下:
- Objective-C 实现
- (UIWindow *)getValidKeyWindow { if (@available(iOS 13.0, *)) { for (UIScene *scene in [UIApplication sharedApplication].connectedScenes) { if (scene.activationState == UISceneActivationStateForegroundActive) { UIWindowScene *windowScene = (UIWindowScene *)scene; for (UIWindow *window in windowScene.windows) { if (window.isKeyWindow) { return window; } } } } } // 适配iOS 12及更低版本 return [UIApplication sharedApplication].keyWindow; }
- Swift 实现
func getValidKeyWindow() -> UIWindow? { if #available(iOS 13.0, *) { return UIApplication.shared.connectedScenes .filter { $0.activationState == .foregroundActive } .compactMap { $0 as? UIWindowScene } .first?.windows .first(where: \.isKeyWindow) } else { return UIApplication.shared.keyWindow } }
最优方案
如果App全局有自定义的UIApplicationDelegate实现,直接持有初始化时创建的window属性,业务逻辑需要用到时直接从AppDelegate的属性取值,不需要从UIApplication单例遍历,性能最优且全版本兼容。
Beta版本问题说明
该时序异常仅存在于iOS 15早期Beta版本,Xcode GM版以及iOS 15正式版已经修复了该问题,如不需要兼容Beta测试用户,等待正式版发布后更新适配包即可,无需修改现有代码逻辑。
内容的提问来源于stack exchange,提问作者Renato Stauffer
相关产品推荐
相关产品推荐

