UIAlertViewController 的异常行为

Unusual behavior with UIAlertViewController

我简单地使用了 UIAlertViewController,我在其中将按钮标签和操作函数作为参数传递给名为 showAlert() 的函数,该函数设置并调用警报。我在 in 闭包的 UIAlertAction 中有动作函数。

异常行为:操作函数在执行 showAlert 时立即执行,而不是在按下按钮时执行。

另一个问题是按下按钮时警报会自动解除。我没有解雇声明。

    class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

    }

    func test1() {
        NSLog("test 1 executed")
    }




    @IBAction func show(_ sender: UIButton) {
        self.showAlert(title: "Title", message: "Message",titleString: "A,B,C", function:test1())
    }
    func showAlert(title: String, message: String, titleString: String, function: ()) {
        let cancelButtonTitle = NSLocalizedString("Cancel", comment: "")
        let labels = titleString.components(separatedBy: ",")
        var actions = [UIAlertAction()]
        for label in labels {
            let a = UIAlertAction(title: label, style: .default) { action in
                function // executed as soon as showAlert is called!! 
                         // Expecting to be called when button is pressed
                NSLog("\(label) Pressed")

            }
            actions.append(a)
        }

        let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)

        // Create the actions.
        let cancelAction = UIAlertAction(title: cancelButtonTitle, style: .cancel) { action in
            NSLog("Cancel Button pressed.")
        }
        for action in actions {
            alertController.addAction(action)
        }
        // Add the actions.
        alertController.addAction(cancelAction)

        present(alertController, animated: true, completion: nil)
    }

}

控制台上的响应是: 2017-05-11 11:55:15.593 AlertTest[5304:8818290] 函数执行 2017-05-11 11:55:25.287 AlertTest[5304:8818290] A Pressed

记住这一点:

Adding ()s to the end of a method/function name will call the method. Remove the ()s to "refer" to that method/function.

当你这样做时:

//                                                                           I mean this
//                                                                                 |
//                                                                                 v 
self.showAlert(title: "Title", message: "Message",titleString: "A,B,C", function:test1())

您正在调用 test 并将其 return 值用作 showAlert 的参数。

到达该行时,首先调用 test() 来评估其 return 值,然后调用 showAlert,因此控制台输出。

引用方法test,去掉()

self.showAlert(title: "Title", message: "Message",titleString: "A,B,C", function:test1)

你也把参数类型写错了。没有参数且 return 没有任何参数的函数类型应该是 () -> Void:

func showAlert(title: String, message: String, 
    titleString: String, function: () -> Void) {

此外,在警报闭包中,将 () 添加到函数中,因为您现在正在尝试调用它:

let a = UIAlertAction(title: label, style: .default) { action in
    function() // Note the ()s
    NSLog("\(label) Pressed")

}

P.S。我不认为让所有按钮做同样的事情是你真正想要的。不过我可能是错的。