你应该如何处理UIAlertAction的闭包参数

时间:2016-11-30 16:48:44

标签: swift closures uialertaction

我一直在尝试创建一个也有处理程序的UIAlertAtion。我从this问题中读到答案并知道如何去做。

我的问题只是关于它的关闭部分。

1)我知道我可以写:{alert in println("Foo")}{_ in println("Foo")}无法{println("Foo")}。在评论here中解释了因为您需要处理参数操作

这是否意味着由于处理程序的类型为(UIAlertAction) -> Void)?,我必须始终捕获传递的alertAction?

2) 我也读过this,答案基本上是说你可以传递一个函数作为你的参数,但函数应该采用类型为UIAlertAction -> Void的东西,我写道:

private func anything(action : UIAlertAction) {
    print("hello")
}

然后写了我的alertaction:

let anotherAction = UIAlertAction(title: "hi", style: UIAlertActionStyle.Default,
 handler: anything(action)) // error: Use of unresolved identifier 'action'

困惑为什么我得到那个错误

第3) 在评论中它还说:但除此之外,你不必在swift中编写UIAlertActionStyle.Default。 .Default也有效

我尝试写不使用该样式,因此它将默认为.Default

let sendLogAction = UIAlertAction(title: "Log") { action in print("goodbye")}

但后来我收到以下错误:

  

'(标题:字符串,(_) - >())' (又名'(标题:字符串,_ - >())')不是   可转换为'(标题:字符串?,样式:UIAlertActionStyle,处理程序:   ((UIAlertAction) - > Void)?)' (又名'(标题:可选,风格:   UIAlertActionStyle,handler:Optional()>)'),元组   拥有不同数量的元素

4) 另请阅读this回答。我不明白为什么我们需要传递alert这没有任何意义。它并不像我们不知道什么是警报的类型是......我们已经定义了它的类型?!!任何人都可以解释一下通过动作本身会有用的地方,我的意思是我们可以用它做什么?

我知道这是4个问题,但我认为这只是一个基本问题。我有很多read,在一个我在工作场所工作和玩耍的项目中使用了闭包/完成处理程序,但我仍感到困惑。

3 个答案:

答案 0 :(得分:3)

  1. 是的,你必须始终处理这个论点。它是签名的一部分,不能被忽略。它也是特殊的Swift语法能够删除handler参数,因为它是最后一个参数,它是一个闭包参数。

  2. anything(action)更改为anything,就像您链接到的示例一样。

  3. 你误解了。他们并不是说你可以删除样式参数。他们说你可以从UIAlertActionStyle删除UIAlertActionStyle.Default,这意味着你只需要将.Default作为参数传递给样式参数。

  4. 您需要一个示例,其中处理程序的action参数非常有用。真的没有太多的用途。唯一的属性是标题,样式以及是否启用。后者是没有意义的,因为如果处理程序被调用,你知道它已启用。唯一可能的用途是如果标题或样式需要在处理程序中使用,并且在创建时它们未被硬编码到警报操作中。通过访问处理程序中的标题或样式属性,您可以轻松访问创建操作时使用的实际值。

答案 1 :(得分:1)

rmaddy的答案已经足够了,但作为OP :)我找到了问题的根本原因:

我缺乏理解参数处理程序,处理程序的类型为:(UIAlertAction) -> Void)?,即闭包/函数

处理程序只需要一个函数名,一旦你提供了这个函数,它就会填充该函数的输入本身

传递anything作为处理程序,即函数名称。

UIAlertAction的内部实现有一些行,如handler(action),它将使用类型anything的{​​{1}},注入{{ 1}}(传递给它)最终做(UIAlertAction) -> Void)?

话虽这么说,你的action应该做一些有意义的事情。 (已在rmaddy的评论中讨论过)

另一个解决方案是提供一个函数,而是在尾随闭包中使用捕获的操作,并做任何你喜欢做的事情。

anything(action)

这种切换只有在您动态获取代码 时才有价值,否则没有为您知道它的值的切片添加值。

答案 2 :(得分:0)

1)UIAlerAction init方法定义需要3个参数,最后一个参数是(UIAlertAction - > Void)?这意味着你可以有一个'无名'功能(又名闭包)或一个零(由可选符号?指定)。如果您选择不指定最后一个参数,则可以像这样创建UIAlertController

alert.addAction(UIAlertAction(title: "test", style: .default, handler: nil))

但是如果你想指定最后一个参数(不是nil)那么你必须提供一个闭包,它将UIAlertAction作为参数并且不返回任何内容(Void)。引用你的链接,他只是使用他已经创建的'alert'常量来简化。

回答你的问题'这意味着......。',答案是肯定的,因为第三个论点的定义:(UIAlertAction) - >无效)?

2)您收到错误是因为您传递了参数(action)。试试吧

anotherAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.Default,
 handler: anything)

你不应该得到错误。

3)UIAlertAction只有(我相信)一个init方法,所以你需要提供所有三个参数来创建它。看我的1)答案的样式:.default。这是一种调用Swift Enums的新方法。顺便说一句,所有枚举必须是小写的。默认不是。默认中心代码

alert.addAction(UIAlertAction(title: String?, style: UIAlertActionStyle, handler: ((UIAlertAction) -> Void))

4)从答案中可以看出,你有链接。您可以使用常量“警报”(UIAlertAction)随意执行任何操作,例如检查样式并执行某些操作。

func anything(alert: UIAlertAction!) {
    print("somehandler")
    switch alert.title {
    case "OK"?:
      print("title is OK")
    default:
      print("title is not OK")
    }
  }