Ios 如何在Swift中传递参数未知且返回值为参数的函数
我希望传递一个函数作为参数,因为我处理的是web服务,并且我注意到代码是重复的 片段1Ios 如何在Swift中传递参数未知且返回值为参数的函数,ios,swift,function,parameters,swift2,Ios,Swift,Function,Parameters,Swift2,我希望传递一个函数作为参数,因为我处理的是web服务,并且我注意到代码是重复的 片段1 Service.getAllVouchersUsingCallback() { (response, data, error) -> Void in guard let statusCode = response?.statusCode else { Util.showToastWithMessage(Messages.NO_INTERNET_CONNECTION)
Service.getAllVouchersUsingCallback() { (response, data, error) -> Void in
guard let statusCode = response?.statusCode else {
Util.showToastWithMessage(Messages.NO_INTERNET_CONNECTION)
return
}
switch statusCode {
case 200:
self.loadVouchersWithData(data!)
case 503:
Util.showToastWithMessage(Messages.SERVICES_NOT_AVAILABLE)
default:
Util.showToastWithMessage(Messages.UNEXPECTED_RESPONSE)
}
}
片段2
Service.getAllCategoriesUsingCallback { (response, data, error) -> Void in
guard let statusCode = response?.statusCode else {
Util.showToastWithMessage(Messages.NO_INTERNET_CONNECTION)
return
}
switch statusCode {
case 200:
self.loadAndGetCategories(data!, withInialText: "Category ")
case 503:
Util.showToastWithMessage(Messages.SERVICES_NOT_AVAILABLE)
default:
Util.showToastWithMessage(Messages.UNEXPECTED_RESPONSE)
}
}
重复的部分是当状态代码为nil
时发生的情况,以及当响应为200
时我必须执行的操作。我猜函数签名应该是这样的:
func dealWithWebServiceResponse(response: NSURLResponse?, withData data: NSData?, whichActionIs action: whateverFunctionType)
因此,我想知道如何传递任何函数,即,任何数量的参数或任何数量的返回值,因为在这种情况下,我只传递数据,但可能将来我需要另一种函数
提前感谢。探索返回函数的函数是一个很大的问题。我们有一段代码:
guard let statusCode = response?.statusCode else {
Util.showToastWithMessage(Messages.NO_INTERNET_CONNECTION)
return
}
switch statusCode {
case 200:
// <<================ Right here, we want to do "something different"
case 503:
Util.showToastWithMessage(Messages.SERVICES_NOT_AVAILABLE)
default:
Util.showToastWithMessage(Messages.UNEXPECTED_RESPONSE)
}
我们只想弄清楚在这种情况下,success
是什么。在你的第一个例子中,它是:
{ self.loadVouchersWithData($0) }
在你的第二个例子中:
{ self.loadAndGetCategories($0, withInialText: "Category ") }
这两个函数都接受NSData
,但不返回任何内容,就像我们想要的那样
因此,我们需要一种方法来获取第一块代码和插件,这会发生变化。我们需要一个函数,它接受一个“on success”函数并返回一个“handle all stuff”函数。让我们把它写下来:
func successHandler(success: (NSData) -> Void) -> (NSHTTPURLResponse?, NSData?, NSError?) -> Void {
return { (response: NSHTTPURLResponse?, data: NSData?, error: NSError?) in
guard let statusCode = response?.statusCode else {
Util.showToastWithMessage(Messages.NO_INTERNET_CONNECTION)
return
}
switch statusCode {
case 200:
success(data!) // <==== Here's the part that changes!
case 503:
Util.showToastWithMessage(Messages.SERVICES_NOT_AVAILABLE)
default:
Util.showToastWithMessage(Messages.UNEXPECTED_RESPONSE)
}
}
}
这是一个函数,它接受一个函数,该函数接受一个NSData,但不返回任何内容,整个函数返回一个函数,该函数接受一个响应、数据、错误元组,但不返回任何内容。想一想。你真的想让它深入人心,因为它真的,真的很强大
好的,希望这开始有点下沉,所以我要继续。语法非常庞大,所以Swift给了我们一个很好的技巧来简化它,称为currying:
func successHandler(success: (NSData) -> Void)(response: NSHTTPURLResponse?, data: NSData?, error: NSError?) {
guard let statusCode = response?.statusCode else {
Util.showToastWithMessage(Messages.NO_INTERNET_CONNECTION)
return
}
switch statusCode {
case 200:
success(data!) // <==== Here's the part that changes!
case 503:
Util.showToastWithMessage(Messages.SERVICES_NOT_AVAILABLE)
default:
Util.showToastWithMessage(Messages.UNEXPECTED_RESPONSE)
}
}
(我知道这可能看起来不太简单,但事实上确实如此,而且它确实让函数的其余部分变得更简单。)
这(几乎)与之前的声明完全相同。在那条线上调解一会儿。注意f(x:T)(y:U)
双括号语法。请注意,我可以在末尾将->Void
放在何处
咖喱就像现在传递一些参数,以后再传递其余的参数
好的,那么我们如何使用它呢
Service.getAllVouchersUsingCallback(successHandler{ self.loadVouchersWithData($0) })
Service.getAllCategoriesUsingCallback(successHandler{ self.loadAndGetCategories($0, withInialText: "Category ") })
我们调用需要一个(响应、数据、错误)的东西,并用一个获取数据的函数将调用successHandler
的结果传递给它
这将消除你所说的所有重复。这是一个特别复杂的currying版本,因为有很多级别的函数。但它也显示了这项技术的强大
您可能想暂时搁置这一点,然后返回到更简单的介绍,例如。然后,当这有意义时,回到这里。不清楚这其中的哪一部分是重复的,因为您只给出了一个示例。你能演示一下第二个是什么样子的,它有你想要提取的重复代码吗?(那可能是除了
NSData->()
?)以外的任何东西)@RobNapier,我刚刚更新了我的问题。正如您所看到的,代码非常相似,但是当响应为200时,操作会发生变化。@RobNaiper,哇!我非常感谢你花时间回答我的问题。你的回答很清楚,很有价值。我非常感谢你们所做的一切。@RobNapier真正的史诗般的和有益的展览!我希望在我即将到来的项目中使用它。@Rob Naiper,对我有效的是self.successHanler{self.loadVouchersWithData($0)}(response:response,whichdata:data)
。
func successHandler(success: (NSData) -> Void)(response: NSHTTPURLResponse?, data: NSData?, error: NSError?) {
guard let statusCode = response?.statusCode else {
Util.showToastWithMessage(Messages.NO_INTERNET_CONNECTION)
return
}
switch statusCode {
case 200:
success(data!) // <==== Here's the part that changes!
case 503:
Util.showToastWithMessage(Messages.SERVICES_NOT_AVAILABLE)
default:
Util.showToastWithMessage(Messages.UNEXPECTED_RESPONSE)
}
}
func successHandler(success: (NSData) -> Void)(response: NSHTTPURLResponse?, data: NSData?, error: NSError?) {
Service.getAllVouchersUsingCallback(successHandler{ self.loadVouchersWithData($0) })
Service.getAllCategoriesUsingCallback(successHandler{ self.loadAndGetCategories($0, withInialText: "Category ") })