2019-08-22 关于window 你的理解够吗?

    override func viewDidLoad() {
        super.viewDidLoad()
        print(view.window)
        print(UIApplication.shared.keyWindow)
        print(UIApplication.shared.windows[0])
        print(UIApplication.shared.delegate?.window)
        print("")
    }
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        var alter  = UIAlertController.init(title: "测试", message: "备注", preferredStyle: .alert)
        present(alter, animated: true) {
            
        }
        var label = FpsLabel()
        label.show()
        print(view.window)
        print(UIApplication.shared.keyWindow)
        print(UIApplication.shared.windows[0])
        print(UIApplication.shared.delegate?.window)
    }

输出结果是:


2019-08-22 关于window 你的理解够吗?_第1张图片
输出结果

由上面结果可见

UIApplication.shared.windows
        //不需要解包,貌似始终有值,在AppDelegate的创建初期为空数组,这么调用也有风险
UIApplication.shared.keyWindow
        //解包一次,初始值在viewController初期可能为空
UIApplication.shared.delegate?.window
        //必须要解包两次 双层可选值,但是足够安全
self.view.window
        // 只需解包一次,初始值在viewController初期可能为空 

这里让我感兴趣是的双层可选值,就是一层解包解出来还是可选值。
请问系统是怎么实现这种类型的呢?

unowned(unsafe) open var delegate: UIApplicationDelegate?

这样的属性定义的变量,意味着第一层解包解到这里就停止了。

guard let keyWindow =  UIApplication.shared.delegate?.window , let key = keyWindow else {
   return
 }
// 或者这种写法,先将UIWindow??类型强制转为UIWidow?的类型,然后才开始解包       
guard let key = UIApplication.shared.delegate?.window as? UIWindow else {
 return
}

好了。探索到此为止

你可能感兴趣的:(2019-08-22 关于window 你的理解够吗?)