无法从处理程序访问类中存在的变量

Rai*_*bal 4 iphone ios swift swift2 swift3

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))

    }



}
Run Code Online (Sandbox Code Playgroud)

我不知道如何icnNum从处理程序访问它.我得到了以下错误.我知道我无法直接访问该变量但是方式是什么.

实例成员'icnNum'不能用于'ViewController'类型

flo*_*ger 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))
        }   
    }
}
Run Code Online (Sandbox Code Playgroud)

编译器将强制您编写self.icnNum而不是icnNum明确表示闭包将持有对self的引用.

将stopHandler闭包存储为变量,就像在示例中一样,将创建循环引用.您的ViewController实例拥有对stopHandler闭包的强引用,闭包拥有对self的强引用(这是指向ViewController实例的指针).

如果要重用stopHandler,请更新

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))      
    }
}
Run Code Online (Sandbox Code Playgroud)

注意[weak self]何时设置stopHandler闭包.这将防止闭合保持对自身的强引用并避免上述循环引用.

更多详细信息,请访问:https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/AutomaticReferenceCounting.html#//apple_ref/doc/uid/TP40014097-CH20-ID57