@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呢?
问题有点多,代码中一出现闭包我就晕了,希望有大神可以详细回答一下,拜谢。
某草草2017-06-24 09:46:21
上面代码没有必要加上[unowned self], 因为block内部没有循环引用
action
是UIAlertAction 便利构造函数public convenience init(title: String?, style: UIAlertActionStyle, handler: ((UIAlertAction) -> Swift.Void)? = nil)
中handler这个block的参数.上面是因为swift尾随闭包写法.等价于:
textFields
是UIAlertController
中的可变数组var textFields: [UITextField]?
guard是对textFields
可选属性进行可选绑定, textField
是可选值解包非nil后的值,当textFields可选值为nil时, 将不执行后面的代码.
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
unowned关键字和weak都用于打破循环引用,与 weak不同的是通常情况下当能够保证所引用的实例具有更长的生命周期时,使用owned, 此时ARC不会自动将实例置为nil。但是我认为上述代码没有必要加[onowned self],这里我没有看出来哪里会产生循环引用。
[unowned self]后面跟的action表示是闭包的参数,因为UIAlertAction的构造函数的最后一个参数需要一个UIAlertAction!类型的参数,如下:
convenience init(title title: String!, style style: UIAlertActionStyle, handler handler: ((UIAlertAction!) -> Void)!)
guard let textField = alert.textFields?.first,
let nameToSave = textField.text else {return}
这段代码的意思是只有alert.textFields?.first不为空时才会执行后续的逻辑,否则直接返回。其中第二个let只有在第一个let的textField不为nil时才能执行。这是swift中的常见用法,具体的你可以看看文档。