VisionOS中UIKit手动创建Window时应用崩溃问题求助
问题
基于Xcode模板创建基础UIKit应用,手动移除Storyboard加载逻辑、自行创建应用窗口后,在iPhone/iPad模拟器运行正常,但在visionOS模拟器中崩溃。
SceneDelegate中创建窗口的代码:
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { print("SceneDelegate - willConnectTo session") guard let windowScene = scene as? UIWindowScene else { return } window = UIWindow(windowScene: windowScene) window?.backgroundColor = UIColor.systemBackground window?.rootViewController = ViewController() window?.makeKeyAndVisible() // 在Apple Vision设备中在此处崩溃 }
崩溃发生在window?.makeKeyAndVisible()行,报错信息:
*** Assertion failure in BOOL _UIWindowSceneCompatibleIsHidden(UIWindow *__strong)(), UIWindowScene.m:2732
调试器堆栈跟踪:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Error in UIKit client: window visibility must match its layer visibility!' *** First throw call stack: ( 0 CoreFoundation 0x00000001804a510c __exceptionPreprocess + 172 1 libobjc.A.dylib 0x0000000180082f50 objc_exception_throw + 56 2 Foundation 0x0000000180d41024 -[NSMutableDictionary(NSMutableDictionary) classForCoder] + 0 3 UIKitCore 0x0000000185570000 _UIWindowSceneCompatibleIsHidden + 200 4 UIKitCore 0x0000000185570ca4 -[UIWindowScene _windowUpdatedVisibility:] + 212 5 UIKitCore 0x000000018532f264 -[UIWindow _updateLayerOrderingAndSetLayerHidden:actionBlock:] + 188 6 UIKitCore 0x0000000185330128 -[UIWindow _setHidden:forced:] + 228 7 UIKitCore 0x000000018533f024 -[UIWindow _mainQueue_makeKeyAndVisible] + 36 8 TestMultiWindowCDApp 0x00000001047d073c $s20TestMultiWindowCDApp13SceneDelegateC5scene_13willConnectTo7optionsySo7UISceneC_So0L7SessionCSo0L17ConnectionOptionsCtF + 844 9 TestMultiWindowCDApp 0x00000001047d08a8 $s20TestMultiWindowCDApp13SceneDelegateC5scene_13willConnectTo7optionsySo7UISceneC_So0L7SessionCSo0L17ConnectionOptionsCtFTo + 84 10 UIKitCore 0x00000001847ef76c +[UIScene _sceneForFBSScene:create:withSession:connectionOptions:] + 1012 11 UIKitCore 0x00000001852fafd0 -[UIApplication _connectUISceneFromFBSScene:transitionContext:] + 804 12 UIKitCore 0x00000001852fb2b8 -[UIApplication workspace:didCreateScene:withTransitionContext:completion:] + 356 13 UIKitCore 0x0000000184dda1b4 -[UIApplicationSceneClientAgent scene:didInitializeWithEvent:completion:] + 260 14 FrontBoardServices 0x0000000186e4851c -[FBSScene _callOutQueue_didCreateWithTransitionContext:completion:] + 296 15 FrontBoardServices 0x0000000186e71d48 __92-[FBSWorkspaceScenesClient createSceneWithIdentity:parameters:transitionContext:completion:]_block_invoke.90 + 224 16 FrontBoardServices 0x0000000186e55390 -[FBSWorkspace _calloutQueue_executeCalloutFromSource:withBlock:] + 160 17 FrontBoardServices 0x0000000186e71ac0 __92-[FBSWorkspaceScenesClient createSceneWithIdentity:parameters:transitionContext:completion:]_block_invoke + 284 18 libdispatch.dylib 0x0000000105a567e4 _dispatch_client_callout + 16 19 libdispatch.dylib 0x0000000105a5a3dc _dispatch_block_invoke_direct + 392 20 FrontBoardServices 0x0000000186e95aa8 __FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__ + 44 21 FrontBoardServices 0x0000000186e95984 -[FBSMainRunLoopSerialQueue _targetQueue_performNextIfPossible] + 196 22 FrontBoardServices 0x0000000186e95adc -[FBSMainRunLoopSerialQueue _performNextFromRunLoopSource] + 24 23 CoreFoundation 0x0000000180405be8 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 24 24 CoreFoundation 0x0000000180405b30 __CFRunLoopDoSource0 + 172 25 CoreFoundation 0x00000001804052f8 __CFRunLoopDoSources0 + 320 26 CoreFoundation 0x00000001803ff9b8 __CFRunLoopRun + 768 27 CoreFoundation 0x00000001803ff2b4 CFRunLoopRunSpecific + 572 28 GraphicsServices 0x000000018e9b6c20 GSEventRunModal + 160 29 UIKitCore 0x00000001852f9c70 -[UIApplication _run] + 868 30 UIKitCore 0x00000001852fd910 UIApplicationMain + 124 31 UIKitCore 0x000000018478b890 __swift_destroy_boxed_opaque_existential_1Tm + 10528 32 TestMultiWindowCDApp 0x00000001047cf67c $sSo21UIApplicationDelegateP5UIKitE4mainyyFZ + 120 33 TestMultiWindowCDApp 0x00000001047cf5f4 $s20TestMultiWindowCDApp11AppDelegateC5$mainyyFZ + 44 34 TestMultiWindowCDApp 0x00000001047cf750 main + 28 35 dyld 0x0000000104e9d544 start_sim + 20 36 ??? 0x000000010482e058 0x0 + 4370653272 37 ??? 0x2311800000000000 0x0 + 2526941603419914240 ) libc++abi: terminating due to uncaught exception of type NSException
确认UIWindow(windowScene: windowScene)能成功创建window对象,请问错误含义是什么,如何解决?
错误含义与解决方案
错误含义
这是visionOS的UIKit实现中的特殊一致性检查:窗口的可见性状态必须与其底层图层的可见性状态完全匹配。在visionOS中,UIWindow初始化后的默认可见性逻辑和iOS/iPadOS存在差异,直接调用makeKeyAndVisible()时,窗口图层的可见性还未完成同步,触发了UIKit的断言检查。
解决方法
在调用makeKeyAndVisible()之前,显式设置窗口的isHidden属性为false,确保窗口与图层的可见性状态同步。修改后的代码如下:
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { print("SceneDelegate - willConnectTo session") guard let windowScene = scene as? UIWindowScene else { return } window = UIWindow(windowScene: windowScene) window?.backgroundColor = UIColor.systemBackground window?.rootViewController = ViewController() window?.isHidden = false // 先显式同步可见性状态 window?.makeKeyAndVisible() }
或者拆分操作,单独设置窗口为key:
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { print("SceneDelegate - willConnectTo session") guard let windowScene = scene as? UIWindowScene else { return } window = UIWindow(windowScene: windowScene) window?.backgroundColor = UIColor.systemBackground window?.rootViewController = ViewController() window?.isHidden = false window?.makeKey() // 单独设置为key窗口 }
以上两种方式都能避免visionOS的断言检查,保证应用正常运行。
内容的提问来源于stack exchange,提问作者Z S
相关产品推荐
相关产品推荐

