Swift 闭包与从函数返回值/对象
我目前正在学习Swift(4)/iOS编程。我对面向对象编程相当陌生,但确实有函数式编程的经验。有一个概念让我有些困惑 在我遵循的课程/示例中,函数主要如下所示:Swift 闭包与从函数返回值/对象,swift,function,architecture,closures,swift4,Swift,Function,Architecture,Closures,Swift4,我目前正在学习Swift(4)/iOS编程。我对面向对象编程相当陌生,但确实有函数式编程的经验。有一个概念让我有些困惑 在我遵循的课程/示例中,函数主要如下所示: func getUsername(forUid uid: String, handler: @escaping (_ username: String) -> Void) { //Do stuff handler("MyName") } func getUsername(forUid uid: String) ->
func getUsername(forUid uid: String, handler: @escaping (_ username: String) -> Void) {
//Do stuff
handler("MyName")
}
func getUsername(forUid uid: String) -> String) {
//Do stuff
return "MyName"
}
名称通过闭包传递,我很少看到这样的函数:
func getUsername(forUid uid: String, handler: @escaping (_ username: String) -> Void) {
//Do stuff
handler("MyName")
}
func getUsername(forUid uid: String) -> String) {
//Do stuff
return "MyName"
}
第二种方法是否已弃用,或者该函数是否仍有使用价值。我们何时以及为什么要使用第一个变体?当然,它没有被弃用。
您应该为异步任务使用闭包,否则返回值。通过一个示例更容易获得它。下面是我从API获得的一些位置:
func getPlaces(onSuccess: @escaping(_ places: [Place]?) -> Void, onFailure: @escaping(Error, _ title: String?, _ message: String?) -> Void) {
//perform API request...
//[...]
//...
// Session
session.dataTask(with: requestURL) { (data, response, error) in
guard error == nil else {
//handling Error
onFailure(error!, "Error", error?.localizedDescription)
group.leave()
return
}
//...
//handling succes
else {
var places: [Place] = []
places = responseJson.places!
onSuccess(places)
}
group.leave()
}.resume()
}
group.wait()
return
}
正如你所看到的,我想要处理成功和错误。以下是我如何使用它:
APIManager.shared.getPlaces(onSuccess: { (places) in
//handling success
}
}) { (error, title, message) in
DispatchQueue.main.async {
self.present(getAlertFromError(title: title, message: message), animated: true)
}
}
我们使用第一个变量进行异步编程。例如,请参见
func getUsername(forUid uid: String, handler: @escaping (_ username: String) -> Void) {
DispatchQueue.main.async {
// do some asynchronous stuff
handler("MyName")
}
}
注意handler
必须位于async
闭包内,否则将立即调用该处理程序,因为async
不阻塞。现在,如果我们使用return
而不是handler
,则会出现编译错误,因为您的函数不返回任何值,因此要修复编译错误,它必须位于函数级别(而不是async
块)。如果它不在async
块中,它将立即返回(与上面的第二个handler
案例相同,因此如果您正在执行异步任务,则必须使用闭包。但是,如果您没有使用异步内容,则可以安全地在代码中使用第二个变量
除了异步编程之外,闭包也用于同步编程,例如,函数使用闭包作为参数来定义对象应如何映射。谢谢。我只是不完全习惯异步编程,因此会产生混淆。但现在清楚了:)@paper1111闭包不限于异步行为。它也可以根据上下文同步运行。异步性的易用性只是闭包的一个应用程序。我刚刚添加了一段关于同步闭包的内容。