我尝试在Xcode 8上使用Swift创建此功能。在我使用firebase功能获取网址后,我无法将url
值分配给imageURL
我尝试了一种解决方法 - 将imageURL放在函数之外,并将url
函数指定给self.imageURL
,它完美无缺。但是,我试图将其设为静态函数,因此我无法使用该解决方法。有谁知道如何解决这个问题?
func createImageDownloadURL(path: String) -> URL? {
// Create a reference to the file you want to download
let storage = FIRStorage.storage()
let storageRef = storage.reference()
let imageRef = storageRef.child(path)
var imageURL: URL?
// Fetch the download URL
imageRef.downloadURL { (url: URL?, error: Error?) in
if error != nil {
// Handle any errors
print(error!)
} else {
// Get the download URL for image
DispatchQueue.main.async {
// Run UI Updates
print(imageURL) // output looks perfectly fine
imageURL = URL(string: url!.absoluteString) // This is where the problem is
}
}
}
print(imageURL) // output is "nil"
return imageURL
}
答案 0 :(得分:2)
这就是你所需要的:)
func createImageDownloadURL(path: String,completionBlock : @escaping (URL?) -> ()) {
// Create a reference to the file you want to download
let storage = FIRStorage.storage()
let storageRef = storage.reference()
let imageRef = storageRef.child(path)
var imageURL: URL?
// Fetch the download URL
imageRef.downloadURL { (url: URL?, error: Error?) in
if error != nil {
// Handle any errors
print(error!)
} else {
// Get the download URL for image
DispatchQueue.main.async {
// Run UI Updates
print(imageURL) // output looks perfectly fine
imageURL = URL(string: url!.absoluteString) // This is where the problem is
completionBlock(imageURL)
}
}
}
}
您的代码有什么问题?
imageRef.downloadURL {和DispatchQueue.main.async {都是异步执行的。因此return imageURL
甚至在任何这些块完成执行之前就会被执行:)
解决方案:
解决方案1:
你可以使用闭包:)你可以接受一个块/闭包作为你的函数参数,并在你得到imageURL时异步执行它:)
解决方案2:
您可以使用Protocol / delegate模式并调用委托方法并将imageURL传递给委托:)
解决方案3 :(不建议)
如果你想不惜任何代价返回(虽然不建议)使用信号量并阻止线程的执行,一旦你有了imageURL释放信号量并执行return语句:)