@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)
}
Do you know what [unowned self] does in the above code? I know it is to prevent loops, but this code is a bit hard to understand. What and what loops are being prevented?
The more important question is, what is the action behind [unowned self]? It seems to appear out of thin air. I don’t know what it means, but without it, the code will report an error.
guard let textField = alert.textFields?.first,
let nameToSave = textField.text else {return}
What do the above two codes mean? What does "alert.textFields?.first" mean? Why can this alert reference textfield before adding textfield?
There are a lot of questions. I get dizzy when closures appear in the code. I hope someone can answer them in detail. Thank you.
某草草2017-06-24 09:46:21
There is no need to add [unowned self] to the above code, because there is no circular reference inside the block
action
is the parameter of handler block in UIAlertAction convenience constructor public init(title: String?, style: UIAlertActionStyle, handler convenience: ((UIAlertAction) -> Swift.Void)? = nil)
. Above It’s because of Swift’s trailing closure writing method. It’s equivalent to:
textFields
is a mutable array in UIAlertController
var textFields: [UITextField]?
guard is an optional binding to the optional property of textFields
, textField
is an optional value unpacking non-nil The value after , when the optional value of textFields is nil, the following code will not be executed.
let saveAction = UIAlertAction(title: "", style: .default, handler: { action in
guard let textField = alert.textFields?.first,
let nameToSave = textField.text else {return}
self.names.append(nameToSave)
self.tableView.reloadData()
})
过去多啦不再A梦2017-06-24 09:46:21
The unowned keyword and weak are both used to break reference cycles. Unlike weak, owned is usually used when it is guaranteed that the referenced instance has a longer life cycle. In this case, ARC will not automatically set the instance to nil. . But I think there is no need to add [onowned self] to the above code. I don't see where a circular reference will occur here.
The action followed by[unowned self] represents the parameter of the closure, because the last parameter of the constructor of UIAlertAction requires a parameter of type UIAlertAction!, as follows:
convenience init(title title: String!, style style: UIAlertActionStyle, handler handler: ((UIAlertAction!) -> Void)!)
guard let textField = alert.textFields?.first,
let nameToSave = textField.text else {return}
The meaning of this code is that subsequent logic will be executed only when alert.textFields?.first is not empty, otherwise it will be returned directly. The second let can only be executed when the textField of the first let is not nil. This is a common usage in swift. You can check the documentation for details.