iOS中UIWindow在AppDelegate与SceneDelegate中的行为疑问
场景1:自定义命名的UIWindow
UIKit识别和管理UIWindow,完全不依赖你给属性起的名字——核心看的是对象类型以及它和UIWindowScene的绑定关系。
当你在SceneDelegate中创建UIWindow实例,并且把它的windowScene属性赋值给当前的scene对象时,UIKit内部会自动追踪这个window。哪怕你定义多个不同名字的UIWindow属性,只要每个都正确关联了对应的windowScene,UIKit都会把它们纳入管理体系。变量名只是你代码里的标识,和UIKit的内部逻辑完全无关。
场景2:UIWindow属性与makeKeyAndVisible
makeKeyAndVisible的作用是把window设为当前scene的**主窗口(key window)**并让它显示,但它并不是将window加入UIApplication.shared.windows的必要条件。
实际上,只要你创建了UIWindow实例,并且给它的windowScene属性赋值了有效的UIWindowScene对象,这个window就会被自动添加到windows数组中。makeKeyAndVisible只是额外完成了激活窗口、设置可见性这两个操作,window的注册在关联windowScene的那一刻就已经完成了。
场景3:断点下的UIWindow行为
这是**ARC(自动引用计数)**的生命周期导致的差异:
当你不在SceneDelegate中用强引用属性持有UIWindow时,window对象在创建完成后,没有其他强引用保留它,ARC会在当前代码块执行结束后立即释放它。但设置断点时,代码执行暂停,此时window还没被释放,所以它依然存在于windows数组并能显示;没有断点时,代码执行流畅完成,window被快速释放,没有可用的window承载界面内容,就会出现黑屏。本质是断点临时延长了window的生命周期,让UIKit能临时持有它,一旦断点取消,对象被释放就无法维持显示了。
内容的提问来源于stack exchange,提问作者Alisher Baigazin

