使用 Swift 闭包捕获变量
Using a Swift closure to capture a variable
我有这段代码,它显然出错了,因为当我在 return 语句中使用 FOO 时,它超出了函数的范围。我知道(我想我知道)我需要使用闭包来捕获变量,但我不知道该怎么做。使用 Alamofire 和 SwiftyJSON。任何帮助都会很棒!谢谢!
func getPlayerID(named: String) -> String {
Alamofire.request(.GET, "URL", headers: headers)
.responseJSON { response in
let json = JSON.self(response.result.value!)
for var index = 0; index < json.count; index++ {
if json[index]["Name"].stringValue == named {
var FOO = json[index]["FOO"].stringValue
} // If Statement End
} // For Loop End
} // Alamofire Request End
// Return Statement for getPLayerID Function
return FOO
} // getPlayerID Function End
} // Player Struct End
基本思想是 getPlayerID
不应该 return 任何东西,而应该只有一个参数,它是一个闭包,一旦你检索到你想要的值 "return" ,您使用该值作为参数调用闭包。
但是,我建议在这里进行各种其他改进:
- 构建一个字符串数组 return
- 检查
result
是否是 .Failure
,因为您无法控制可能出现的各种 server/network 问题
- 更改闭包以检测和报告错误
但希望这能说明基本思想:
就我个人而言,我 (a) 将 String
参数设为 completionHandler
可选参数; (b) 添加另一个可选的错误参数;和 (c) 将错误处理添加到 getPlayerID
:
func getPlayerID(completionHandler: ([String]?, ErrorType?) -> Void) {
Alamofire.request(.GET, "URL", headers: headers)
.responseJSON { request, response, result in
switch (result) {
case .Success(let value):
let json = JSON.self(value)
// variable to hold all of the results
var strings = [String]()
// populate the array of strings
for var index = 0; index < json.count; index++ {
if json[index]["Name"].stringValue == named {
strings.append(json[index]["FOO"].stringValue)
}
}
// call the completion handler with the strings
completionHandler(strings, nil)
case .Failure(_, let error):
completionHandler(nil, error)
}
}
}
然后,当你想调用它时:
getPlayerID() { strings, error in
// use `strings` here
}
// but not here
如果您发出异步请求,则您无法 return 在同一函数中收到响应中的值,因为请求通过网络发送到服务器并返回需要时间。解决这个问题的最好方法是将回调参数添加到您的函数而不是 return 值。
func getPlayerID(named: String, callback:(foo:String)->()) {
Alamofire.request(.GET, "URL", headers: headers)
.responseJSON { response in
let json = JSON.self(response.result.value!)
for var index = 0; index < json.count; index++ {
if json[index]["Name"].stringValue == named {
var FOO = json[index]["FOO"].stringValue
callback(foo: FOO) // you fire callback here..
} // If Statement End
} // For Loop End
} // Alamofire Request End
} // getPlayerID Function End
回调是一个块对象,将在收到您的响应时触发。因此,如果没有响应(例如,互联网连接中断),回调将永远不会触发。
如何使用它的示例:
self.getPlayerID("ototo") { (foo) -> () in
print("foo received = \(foo)")
}
发送请求和接收响应之间也有一个时间跨度。因此,在您的应用程序的 UI 中添加 UIActivityIndicatorView 直到响应到达(并在互联网连接突然中断时处理超时)是一个很好的做法。
我有这段代码,它显然出错了,因为当我在 return 语句中使用 FOO 时,它超出了函数的范围。我知道(我想我知道)我需要使用闭包来捕获变量,但我不知道该怎么做。使用 Alamofire 和 SwiftyJSON。任何帮助都会很棒!谢谢!
func getPlayerID(named: String) -> String {
Alamofire.request(.GET, "URL", headers: headers)
.responseJSON { response in
let json = JSON.self(response.result.value!)
for var index = 0; index < json.count; index++ {
if json[index]["Name"].stringValue == named {
var FOO = json[index]["FOO"].stringValue
} // If Statement End
} // For Loop End
} // Alamofire Request End
// Return Statement for getPLayerID Function
return FOO
} // getPlayerID Function End
} // Player Struct End
基本思想是 getPlayerID
不应该 return 任何东西,而应该只有一个参数,它是一个闭包,一旦你检索到你想要的值 "return" ,您使用该值作为参数调用闭包。
但是,我建议在这里进行各种其他改进:
- 构建一个字符串数组 return
- 检查
result
是否是.Failure
,因为您无法控制可能出现的各种 server/network 问题 - 更改闭包以检测和报告错误
但希望这能说明基本思想:
就我个人而言,我 (a) 将 String
参数设为 completionHandler
可选参数; (b) 添加另一个可选的错误参数;和 (c) 将错误处理添加到 getPlayerID
:
func getPlayerID(completionHandler: ([String]?, ErrorType?) -> Void) {
Alamofire.request(.GET, "URL", headers: headers)
.responseJSON { request, response, result in
switch (result) {
case .Success(let value):
let json = JSON.self(value)
// variable to hold all of the results
var strings = [String]()
// populate the array of strings
for var index = 0; index < json.count; index++ {
if json[index]["Name"].stringValue == named {
strings.append(json[index]["FOO"].stringValue)
}
}
// call the completion handler with the strings
completionHandler(strings, nil)
case .Failure(_, let error):
completionHandler(nil, error)
}
}
}
然后,当你想调用它时:
getPlayerID() { strings, error in
// use `strings` here
}
// but not here
如果您发出异步请求,则您无法 return 在同一函数中收到响应中的值,因为请求通过网络发送到服务器并返回需要时间。解决这个问题的最好方法是将回调参数添加到您的函数而不是 return 值。
func getPlayerID(named: String, callback:(foo:String)->()) {
Alamofire.request(.GET, "URL", headers: headers)
.responseJSON { response in
let json = JSON.self(response.result.value!)
for var index = 0; index < json.count; index++ {
if json[index]["Name"].stringValue == named {
var FOO = json[index]["FOO"].stringValue
callback(foo: FOO) // you fire callback here..
} // If Statement End
} // For Loop End
} // Alamofire Request End
} // getPlayerID Function End
回调是一个块对象,将在收到您的响应时触发。因此,如果没有响应(例如,互联网连接中断),回调将永远不会触发。 如何使用它的示例:
self.getPlayerID("ototo") { (foo) -> () in
print("foo received = \(foo)")
}
发送请求和接收响应之间也有一个时间跨度。因此,在您的应用程序的 UI 中添加 UIActivityIndicatorView 直到响应到达(并在互联网连接突然中断时处理超时)是一个很好的做法。