@IBAction func addName(_ sender: AnyObject) {
let alert = UIAlertController(title: "New Name", message: "Add a new name", preferredStyle: .alert)
let saveAction = UIAlertAction(title: "Save", style: .default) {
[unowned self] action in
guard let textField = alert.textFields?.first,
let nameToSave = textField.text else {return}
self.names.append(nameToSave)
self.tableView.reloadData()
}
let cancelAction = UIAlertAction(title: "Cancel", style: .default)
alert.addTextField()
alert.addAction(saveAction)
alert.addAction(cancelAction)
present(alert, animated: true)
}
有沒有知道上面程式碼中的[unowned self]是什麼作用?我知道是防止循環,但這段程式碼有點看不太懂,防止的是什麼和什麼的循環呢?
更重要的問題是,[unowned self] 後面的action是什麼東西呢?好像憑空出現的,不知道是什麼意思,但是少了它程式碼又會報錯。
guard let textField = alert.textFields?.first,
let nameToSave = textField.text else {return}
上面兩句程式碼又分別是什麼意思呢? 「alert.textFields?.first」是什麼意思?為什麼這個alert還沒有加入textfield已經能引用textfield?
問題有點多,程式碼中一出現閉包我就暈了,希望有大神可以詳細回答一下,拜謝。
上面程式碼沒有必要加上[unowned self], 因為block內部沒有循環引用
action
是UIAlertAction 便利建構子public convenience init(title: String?, style: UIAlertActionStyle, handler: ((UIAlertAction) -> Swift.Void)? = nil)
中handler是這個參數的參數.因為swift尾隨閉包寫法.等價於:textFields
是UIAlertController
中的可變數組var textFields: [UITextField]?
guard是對
textFields後的值,當textFields可選值為nil時, 將不執行後面的程式碼.
unowned關鍵字和weak都用於打破循環引用,與weak不同的是通常情況下當能夠保證所引用的實例具有更長的生命週期時,使用owned, 此時ARC不會自動將實例置為nil 。但是我認為上述程式碼沒有必要加[onowned self],這裡我沒有看出來哪裡會產生循環引用。
[unowned self]後面跟著的action表示是閉包的參數,因為UIAlertAction的建構子的最後一個參數需要一個UIAlertAction!類型的參數,如下:
convenience init(title title: String!, style style:AlertActionStyle, UI handler handler: ((UIAlertAction!) -> Void)!)
這段程式碼的意思是只有alert.textFields?.first不為空時才會執行後續的邏輯,否則直接回傳。其中第二個let只有在第一個let的textField不為nil時才能執行。這是swift中的常見用法,具體的你可以看看文件。