闭包与从函数返回值/对象

时间:2018-07-16 10:51:12

标签: swift function architecture closures swift4

我目前正在学习Swift(4)/ iOS编程。我是OOP的新手,但是确实有函数式编程的经验。有一个概念使我有些困惑...

在课程/示例中,我遵循的功能主要是这样的:

func getUsername(forUid uid: String, handler: @escaping (_ username: String) -> Void) {
//Do stuff    
handler("MyName")
}

名称是由闭包传递的,我几乎看不到像这样的函数:

func getUsername(forUid uid: String) -> String) {
//Do stuff    
 return "MyName"
}

是不推荐使用的第二种方法,还是该功能仍然有用。我们何时以及为什么使用第一个变体?

3 个答案:

答案 0 :(得分:1)

我们将第一个变量用于异步编程。例如,请参见

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情况相同,因此,如果要执行异步任务,则必须 使用闭包。) ,如果您不使用异步内容,则可以安全地在代码中使用第二个变体。

除了异步编程外,闭包也用于同步编程中,例如,map函数使用闭包作为参数来定义对象的映射方式。

答案 1 :(得分:0)

当然它不被弃用。 您应该对异步任务使用闭包,否则返回值。

答案 2 :(得分:0)

通过示例更容易获得它。这是我从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)
        }
    }