Swift 完成处理程序 - 转义尾随闭包

Posted

技术标签:

【中文标题】Swift 完成处理程序 - 转义尾随闭包【英文标题】:Swift completion handler - escaping trailing closure 【发布时间】:2017-10-20 20:41:34 【问题描述】:

我现在已经阅读了很多关于带有闭包、尾随闭包和转义函数的 swift 函数的文章。他们似乎都给出了完全不同的例子,以至于我不明白我自己的功能做错了什么。

我的主要问题是如何执行尾随闭包函数。

我创建了这个函数来将图像上传到 firebase。它需要两个输入并且应该返回一个字符串(imageURL)。我相信这个功能没问题。

func uploadImageToFirebaseAndReturnImageURL(directory: String, image: UIImage!, handler: @escaping(_ imageURL: (ImageURL))  -> ()) 
    let imageName = NSUUID().uuidString // create unique image name

    if let uploadData = UIImagePNGRepresentation(image) 
        DB_STORE.child(directory).putData(uploadData, metadata: nil, completion:  (metadata, error) in

            if error != nil 
                print(error)
                return
            

            if let profileImageUrl = metadata?.downloadURL()?.absoluteString 
                let d = ImageURL(imageURL: profileImageUrl)
                handler (d)             
            
            return

        )
    

我的问题是在处理程序方面如何正确执行此功能。 我想首先执行该函数,然后在完成后我想获取 imageURL 并将此变量用于另一个嵌套函数,该函数将这个变量(字符串)上传到 firebase 数据库中。

uploadImageToFirebaseAndReturnImageURL(directory: "profileImage", image: selectedImageFromPicker!, handler:  imageURL in
    guard let uid = Auth.auth().currentUser.uid else  print("User is not logged in"); return 
    DataService.instance.updateUserWithProfileImageURL(uid: uid, imageURL: imageURL)
    print("")

我做错了什么?

【问题讨论】:

【参考方案1】:

要传递一个trailing closure,你需要结束/关闭你的函数调用并且省略闭包参数标签。例如:

func foo(first: Int, second: Int, handler: (Int) -> Void) 
    ...

调用语法:

foo(first: 10, second: 20)  result in
    /* trailing closure body */

顺便说一句,您应该简单地从以下位置声明您的 handler 参数声明:

handler: @escaping (_ imageURL: (ImageURL)) -> ()

到这里:

handler: @escaping (ImageURL) -> Void

使用Void() 是风格问题,因为它们在逻辑上是相同的。我更喜欢前者;)

【讨论】:

Void 是否意味着任何数据类型?所以它可以是一个字符串? 不,应该是AnyVoid 类型只是空元组的别名,即()

以上是关于Swift 完成处理程序 - 转义尾随闭包的主要内容,如果未能解决你的问题,请参考以下文章

当完成处理程序显式使用 @escaping 时,Swift 推断完成处理程序闭包是默认的 @nonescaping 而不是 @escaping

Swift-使用完成处理程序更新闭包外的全局变量

在 Swift 中遇到完成处理程序和闭包问题

swift - 如何从系统函数的完成处理程序闭包中返回?

iOS Swift 如何访问在完成处理程序闭包中创建的数据——在闭包之外

使用可选参数的转义完成处理程序有时会使 Swift 崩溃