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

Swift completion handler - escaping trailing closure

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

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

我创建了这个函数来将图像上传到 firebase。它需要两个输入,并且应该 return 一个字符串 (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("")
}

我做错了什么?

要传递 trailing closure 你需要 end/close 你的函数调用 并且 省略闭包参数标签.例如:

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() 是风格问题,因为它们在逻辑上是相同的。我更喜欢前者 ;)