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))
}
}
I don't know how to access that icnNum
from the handler. Am getting following error. I know that I can't access that variable directly but what is the way.
Define the stopHandler closure inside the showAlert()
function and it should work.
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))
}
}
}
The compiler will force you to write self.icnNum
instead of icnNum
to make it obvious that the closure will hold a reference to self.
Storing the stopHandler closure as a variable, like you did in your example, would create a cyclic reference. Your ViewController instance holds a strong reference to the stopHandler closure, the closure holds a strong reference to self (which is a pointer to you ViewController instance).
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))
}
}
Notice the [weak self]
when setting the stopHandler closure. This will prevent the closure from keeping a strong reference to self and avoid the cyclic reference described above.
More details at: https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/AutomaticReferenceCounting.html#//apple_ref/doc/uid/TP40014097-CH20-ID57
you can write your closer like this way
let stopHandler = {
(icnNum: Int64 ,action:UIAlertAction!) -> Void in
let num = icnNum
}
while calling this closer like this way
alert.addAction(UIAlertAction(title: "Stop", style: .default, handler: stopHandler(self.icnNum, UIAlertAction!)))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With