[英]Why can i use self when I initialize property with a closure?
官方文檔(Swift 4.1)說:
如果使用閉包來初始化屬性,請記住在執行閉包時尚未初始化實例的其余部分。 這意味着您無法從閉包中訪問任何其他屬性值,即使這些屬性具有默認值也是如此。 您也不能使用隱式self屬性,也不能調用任何實例的方法。
所以我想我需要使用lazy var,今天我創建了一個按鈕
let loginRegisterButton: UIButton = {
let button = UIButton(type: .system)
button.backgroundColor = UIColor.rgb(red: 80, green: 101, blue: 161)
button.setTitle("Register", for: .normal)
button.translatesAutoresizingMaskIntoConstraints = false
button.setTitleColor(UIColor.white, for: .normal)
button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 16)
button.addTarget(self , action: #selector(handleRegister), for: .touchUpInside)
return button
}()
所以我只是在addTarget方法中使用self而XCode似乎沒有打擾更多的程序沒有任何錯誤。 一切都很好。所以當我用閉包初始化屬性時,為什么我可以使用self? 是否有一些變化或者我錯過了什么?
很奇怪 - 也許是buggily-你的閉包中的self
評估為一個函數對象。 (Hamish在評論中解釋說,該函數是NSObjectProtocol.self
一種curry形式。)但是,當你稍后問按鈕的目標時,它報告+[NSNull null]
:
let loginRegisterButton: UIButton = {
let button = UIButton(type: .system)
button.backgroundColor = .red
button.setTitle("Register", for: .normal)
button.translatesAutoresizingMaskIntoConstraints = false
button.setTitleColor(UIColor.white, for: .normal)
button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 16)
print(self)
// Output: (Function)
button.addTarget(self, action: #selector(handleRegister), for: .touchUpInside)
let target = button.allTargets.first!.base
print(target, type(of: target))
// Output: <null> NSNull
return button
}()
(使用Xcode 9.3.1測試。)
這個函數會得到變成NSNull
函數對象只是調用之前分配:如下addTarget
,作為傳遞target
參數。 loginRegisterButton
閉包擁有對新分配函數的強引用。
該按鈕將目標存儲為歸零弱引用。
addTarget
返回后,閉包釋放其對該函數的強引用。 這是該函數的唯一強引用,因此Swift釋放該函數。 這將按鈕對函數的弱引用設置為nil。
然后,當我們詢問allTargets
的按鈕時,它構造一個NSSet
。 由於NSSet
不能直接保存nil,因此按鈕會在集合中放置+[NSNull null]
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.