import UIKit
class ViewController: UIViewController
{
var icnNum : Int64 = 0
let stopHandler =
{
(action:UIAlertAction!) -> Void in
let num = icnNum
}
func showAlert( userStatus: String )
{
let alert = UIAlertController(title: "", message: "", preferredStyle: .alert)
alert.title = "What you want to do?"
alert.addAction(UIAlertAction(title: "Stop", style: .default, handler: stopHandler))
}
}
我不知道如何从处理程序访问icnNum
。我得到了以下错误。我知道我无法直接访问该变量但是方式是什么。
答案 0 :(得分:5)
在showAlert()
函数中定义stopHandler闭包,它应该可以工作。
class ViewController: UIViewController
{
var icnNum : Int64 = 0
func showAlert( userStatus: String ) {
let stopHandler = { (action:UIAlertAction!) -> Void in
let num = self.icnNum
}
let alert = UIAlertController(title: "", message: "", preferredStyle: .Alert)
alert.title = "What you want to do?"
alert.addAction(UIAlertAction(title: "Stop", style: .Default, handler: stopHandler))
}
}
}
编译器将强制您编写self.icnNum
而不是icnNum
,以明确闭包将保留对self的引用。
将stopHandler闭包存储为变量,就像在示例中一样,将创建循环引用。您的ViewController实例拥有对stopHandler闭包的强引用,闭包拥有对self的强引用(这是指向ViewController实例的指针)。
class ViewController: UIViewController {
var icnNum : Int64 = 0
var stopHandler: ((action:UIAlertAction!) -> Void)?
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
self.stopHandler = { [weak self] (action:UIAlertAction!) -> Void in
let num = self?.icnNum
}
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func showAlert( userStatus: String )
{
let alert = UIAlertController(title: "", message: "", preferredStyle: .Alert)
alert.title = "What you want to do?"
alert.addAction(UIAlertAction(title: "Stop", style: .Default, handler: stopHandler))
}
}
设置stopHandler闭包时请注意[weak self]
。这将阻止闭包保持对自身的强烈引用并避免上述循环引用。
答案 1 :(得分:2)
你可以这样写近距离
let stopHandler = {
(icnNum: Int64 ,action:UIAlertAction!) -> Void in
let num = icnNum
}
虽然这样称呼它更接近
alert.addAction(UIAlertAction(title: "Stop", style: .default, handler: stopHandler(self.icnNum, UIAlertAction!)))
答案 2 :(得分:1)
您可以将方法作为处理程序传递。这避免了需要在周围浮动的裸露闭合。
class ViewController: UIViewController {
var icnNum : Int64 = 0
func stopHandler(_ action: UIAlertAction) {
let num = icnNum
}
func showAlert(userStatus: String) {
let alert = UIAlertController(title: "", message: "", preferredStyle: .alert)
alert.title = "What you want to do?"
alert.addAction(UIAlertAction(title: "Stop", style: .default, handler: stopHandler))
}
}
<强>更新强>
这样的处理程序的预期行为是使用可以包含本地上下文的闭包。
func showAlert(userStatus: String) {
let localContext = "Local information"
// …
alert.addAction(UIAlertAction(title: "Stop", style: .default) { action in
if localContext == "Local information" {
// Do Something
}
})
}
但是,您没有本地环境。您正在使用的上下文包含在对象实例中。
func showAlert(userStatus: String) {
// …
alert.addAction(UIAlertAction(title: "Stop", style: .default, handler: stopHandler))
}
因为您的处理程序中没有本地使用的内容,所以您不需要关闭。
func stopHandler(_ action: UIAlertAction) {
let num = icnNum
}
将执行与闭包处理程序相同的操作,但会为您提供对象实例的上下文。