You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 18:27:02