处理程序声明不起作用

Posted

技术标签:

【中文标题】处理程序声明不起作用【英文标题】:Declaration of Handlers doesn't work 【发布时间】:2017-11-26 12:13:48 【问题描述】:

我已经阅读了一些关于为 UIAlertViews 声明处理程序的示例,但不知何故我无法掌握正确语法的概念。我看过一些示例,它们执行以下操作之一: - 处理程序:someFunction - handler: action in SomeFunction(“action in”是什么意思?) - handler: _ in print("Foo!") (同样,“in”是什么意思?)

我最担心的是我不知道这些东西是什么意思。我正在尝试使用第一种样式,但是出现以下错误:“变量在其自己的初始值内使用”

let answerVCAlert = UIAlertController(title: "Your turn", message: "What's the answer?", preferredStyle: .alert)
    let submitAnswer = UIAlertAction(title: "Submit", style: .default, handler: submitAnswer(answer: " ")) //grab from textfield

    let noAnswer = UIAlertAction(title: "No Answer", style: .default, handler: submitAnswer(answer: " "))

    func submitAnswer(answer: String) 
        print ("The string passed is \(answer)")
        //compare answer to correct answer
    

    func attemptAnswer() 
        answerVCAlert.addAction(submitAnswer)
        answerVCAlert.addAction(noAnswer)
        //answerVCAlert.addTextField //how ??? too many different examples

        self.present(answerVCAlert, animated: true, completion: nil)
    

【问题讨论】:

你在哪里调用 attempAnswer 方法? “我不知道这些东西是什么意思” – 你会想阅读 Swift 参考中的 Closures 章节。 我读过闭包,知道什么是闭包的概念,也熟悉 Java 中的 lambda 表达式。通常让我失望的是语法的一部分(尤其是在使用“action”或“in”之类的词时,比如你在哪里定义了这个动作或者你的意思是什么(以及为什么?)?)。抱歉,如果在我的 OP 中不清楚,我知道这些概念是什么,但语法让我很着迷,因为每个人都只是给出了我不熟悉的具有这种语法的示例 【参考方案1】:

正如 cmets 中所述,现在是学习如何使用闭包或 completion handlers 的时候了。是时候好好度过了。

这里有一些工作代码(基于您的但有一些小的改动),其中还包括一个文本字段。从警报文本字段中获取文本的一个很好的 Swift 3 示例是 this SO answer。下面的代码中的 Swift 4 语法发生了变化。

我已经缩进了代码,希望它可以帮助您更好地理解完成处理程序。我还添加了一些内联 cmets。

这里是警报:

// I changed the name of your alert controller for brevity

let alertVC = UIAlertController(
    title: "Your turn",
    message: "What's the answer?",
    preferredStyle: .alert)

// Add a textfield called answerText. You may not want the placeholder to be blank.

alertVC.addTextField(configurationHandler: (answerText: UITextField!) in
    answerText.placeholder = "Default answer"
)

// Add a Submit button that will call submitAnswer()

let submitAnswer = UIAlertAction(
    title: "Submit",
    style: .default,
    handler:  action -> Void in
        self.submitAnswer(alertVC.textFields![0])
    )
alertVC.addAction(submitAnswer)

// Add a No Answer button that will call noAnswer()
// NOTE: I changed this to be style of cancel... check out how it's rendered.

let noAnswer = UIAlertAction(
    title: "No Answer",
    style: .cancel,
    handler:  action -> Void in
        self.noAnswer()
    )
alertVC.addAction(noAnswer)

// I think you *want* everybody to try to answer, so let's make that the preferred action.

alertVC.preferredAction = submitAnswer
present(
    alertVC,
    animated: true,
    completion: nil)

结果如下:

func submitAnswer(_ answer: String) 
    print ("The answer is \(answer)")
    //compare answer to correct answer

func noAnswer() 
    print ("Cancel was tapped.")

我所做的更改包括:

将一个操作的样式从 .default 更改为 .cancel,让您了解它的作用。 在完成处理程序调用中添加了self - 它们是必需的。 将submitAnswer() 的签名更改为不再需要参数标签。这样更快捷。 将noAnswer 操作调用从submitAnswer() 更改为noAnswer(),以区分用户点击的内容。

【讨论】:

您好,感谢您提供代码。像这样分解它真的很有帮助。我只有一个问题,为什么或什么是“行动-> 无效”。我在哪里可以准确地阅读这四件事中的每一个的含义。我假设-> Void 意味着它什么也不返回。但是“动作”和“在”真的让我很困惑。这些在哪里定义?它们是确切的词还是变量?我可以用别的词代替这些词吗? 这是理解闭包或完成处理程序的一部分。 @Martin_R 提供的链接以及我提供的链接应该会有所帮助。在我的链接中向下滚动到完成处理程序部分。我刚刚删除了我自己对action -> Void in 的解释,因为我不是这方面的专家。大多数时候我的代码不需要处理程序(我只使用nil),而那些时候我使用我给你的那个链接。它的语法非常强大(而且很奇怪)——你实际上是在将一个函数作为参数传递给警报控制器——而我仍在理解它!

以上是关于处理程序声明不起作用的主要内容,如果未能解决你的问题,请参考以下文章

自定义异步任务的实现不起作用

每秒更新 ListView 处理程序不起作用

带有@Qualifier 的@Bean 声明不起作用

为啥消息处理程序在调试模式下不起作用?

为啥这个调整大小处理程序不起作用? [复制]

Webflux 安全登录失败处理程序不起作用