是否存在非UIWindowScene的UIScene?模板代码写法存疑
UISceneDelegate模板代码相关疑问解答
1. 会不会进入scene(_:willConnectTo:options:)的else分支?
根据UIScene的构造器文档说明:
子类调用此方法初始化场景详情。
UIScene本身是抽象基类,系统不会直接实例化它,只会创建它的子类实例。目前iOS/iPadOS中常见的子类有UIWindowScene(对应App的主窗口场景)、UIExternalDisplayScene(外接显示器场景)。
正常开发流程下,系统传递给该方法的参数必然是UIScene的子类实例,但如果是手动创建了非UIWindowScene的自定义UIScene子类,或者未来系统新增了其他UIScene子类且你的代码未适配,才有可能进入else分支。不过这种情况在日常开发中几乎不会遇到。
2. 使用强制向下转型scene as! UIWindowScene是否更合理?
如果你的App只需要支持普通的窗口场景(绝大多数App都是这种情况),用as!强制转型是可行的,不会有崩溃风险。但模板代码采用guard let的写法属于防御性编程:
- 避免未来系统新增UIScene子类时,代码因强制转型失败崩溃
- 兼容可能存在的自定义UIScene子类场景
两种写法各有优劣,取决于你的App适配范围:仅做普通窗口场景用as!更简洁;需要兼容多场景类型或留未来扩展空间,用guard let更安全。
3. 存在创建自定义UIScene子类的场景吗?
存在,当你需要为特定场景添加专属的生命周期逻辑、状态管理或特殊行为时,可以自定义UIScene子类。
举个例子:针对外接显示器场景,自定义子类来管理外接显示的专属状态与逻辑:
import UIKit // 自定义外接显示器场景子类 class CustomExternalDisplayScene: UIExternalDisplayScene { // 自定义属性:存储外接显示的专属配置 var externalDisplaySettings: ExternalDisplaySettings? override func sceneDidBecomeActive(_ scene: UIScene) { super.sceneDidBecomeActive(scene) // 执行外接场景激活后的专属逻辑,比如加载适配外接屏幕的内容 setupExternalDisplayContent() } private func setupExternalDisplayContent() { // 自定义内容初始化逻辑,比如加载高分辨率的演示素材 guard let settings = externalDisplaySettings else { return } // 根据配置调整显示内容 } } // 自定义配置结构体 struct ExternalDisplaySettings { var resolution: CGSize var contentMode: UIView.ContentMode }
之后需要在Info.plist的UISceneConfigurations中配置这个自定义子类,指定对应的场景类型(比如UIExternalDisplaySessionRoleExternalDisplay),系统就会在创建外接场景时实例化你的自定义子类。
内容的提问来源于stack exchange,提问作者Tobi
相关产品推荐
相关产品推荐

