在swift中使用带有多个参数的闭包

时间:2014-06-09 21:10:08

标签: closures swift

这个问题主要基于这个问题:

Link

主要区别在于我也希望将参数传递给闭包。说我有这样的事情:

func someFunctionThatTakesAClosure(completionClosure: (venues: Dictionary<String, AnyObject>, error: NSError) -> ()) {
        // function body goes here
        var error: NSError?
        let responseDictionary: Dictionary<String, AnyObject> = ["test" : "test2"]
        completionClosure(venues: responseDictionary, error: error!)
    }

这里没有错误。但是当我在主视图控制器中调用此函数时,我尝试了几种方法,但所有结果都存在不同的错误:

venueService.someFunctionThatTakesAClosure(completionClosure(venues: Dictionary<String, AnyObject>, error: NSError){

        })

或者像这样:

venueService.someFunctionThatTakesAClosure((venues: Dictionary<String, AnyObject>, error: NSError){

        })

甚至是这样:

venueService.someFunctionThatTakesAClosure(completionClosure: (venues: Dictionary<String, AnyObject>, error: NSError) -> (){

            });

我可能只是累了,但任何帮助都会非常感激!

4 个答案:

答案 0 :(得分:5)

venueService.someFunctionThatTakesAClosure({
  venues, error in
  // do stuff
})

您可以选择指定类型(但由于编译器知道闭包应该提供什么类型,因此您不必严格遵守:

venueService.someFunctionThatTakesAClosure({
  (venues: Dictionary<String, AnyObject>, error: NSError) -> () in
  // do stuff
})

但是我在你的调用代码中看到了另一个问题:

completionClosure(venues: responseDictionary, error: error!)
//            No Bueno. What if there's no error?    ^^^^^^

你不应该强行打开错误,因为它完全有可能仍然是零。强制展开nil会导致错误。所以你想要这个:

completionClosure(venues: responseDictionary, error: error)

并且您想要更改闭包以获取可选错误。总计:

func someFunctionThatTakesAClosure(completionClosure: (venues: Dictionary<String, AnyObject>, error: NSError?) -> ()) {
    …
    completionClosure(venues: responseDictionary, error: error)
}

// when calling:
venueService.someFunctionThatTakesAClosure({
  (venues: Dictionary<String, AnyObject>, error: NSError?) -> () in
  // do stuff
})

如果您想传递其他参数,请记住,swift优化为要作为最后一个参数传递的闭包(并且它在objective-c API中广泛遵循惯例):

// in venueService:
func someArgAndClosureFunction(arg1: String, arg2: Int, 
                  completionClosure: (venues: Dictionary<String, AnyObject>, error: NSError?) -> ()) {
    // do stuff
}

// When calling:
venueService.someArgAndClosureFunction("string arg 1", arg2: 10) {
  (venues: Dictionary<String, AnyObject>, error: NSError?) -> () in
  // do stuff
}

在这个例子中,我使用trailing closure syntax允许你传递闭包之外的函数调用parens(但它仍然作为最后一个参数传递)。

答案 1 :(得分:1)

由于你的错误是可选的,我会把它作为传递函数的可选参数:

func someFunctionThatTakesAClosure(completionClosure: (venues: Dictionary<String, AnyObject>, error: NSError?) -> ()) {
  // function body goes here
  var error: NSError? = nil
  let responseDictionary: Dictionary<String, AnyObject> = ["test" : "test2"]
  completionClosure(venues: responseDictionary, error: error)
}

然后可以调用它,传递一个闭包,如下所示:

someFunctionThatTakesAClosure { println($0); println($1) }

注意,以上是创建闭包的简写语法变体之一。

答案 2 :(得分:1)

我觉得你可能只是累了:)。

你说你遇到的困难在于调用方法,对吗?您提供的示例都没有传递有效参数,该参数应该是类型为

的闭包

(Dictionary<String, AnyObject>, NSError) -> ()

所以你可以做几件事......

(a)为变量分配一致的闭包,并将变量作为参数传递给方法:

let myClosure: (Dictionary<String, AnyObject>, NSError?) -> () = { venues, error in
    for (key, _) in venues {
        println(key)
    }
}

venueService.someFunctionThatTakesAClosure(myClosure)

(b)传递一个尾随闭包作为方法调用的参数:

venueService.someFunctionThatTakesAClosure {
    venues, error in
    for (key, _) in venues {
        println(key)
    }
}

答案 3 :(得分:0)

将参数传递给闭包的语法围绕in关键字。

很抱歉链接网址...但请查看http://fuckingclosuresyntax.com/并注明in出现的选项。

请参阅array.sort({ (item1, item2) in return item1 < item2 })

item1item2作为2个输入