我试着在Swift中使用多线程来检索并在视图控制器中显示一张图片。但是,用于检索图片的函数位于单独的模型中。我可以将该函数复制粘贴到视图控制器中,但我将多次重复使用此函数,并且更喜欢将其与特定的视图控制器分开。
我目前拥有的函数(同样在我命名为“WikimediaAPI”的单独文件中)如下所示:
上述代码可行,但是不支持多线程,当我从表视图控制器切换到此视图控制器时,时间太长。我尝试按照以下方式实现多线程,但是我无法在异步块中返回任何内容。
我曾经考虑过在异步代码块中返回闭包,而不是UIImage,但我不确定如何实现。如果这样做,我仍然需要在视图控制器中设置图像,这一点我也不确定该怎么做。
以下是在视图控制器中调用该函数的代码:
我正在使用一个字典(wikimediaPageTitleDict)从plist文件中将字符串与正确的维基百科页面(allergy.0是该字符串)关联起来。
感谢任何帮助。谢谢!
我目前拥有的函数(同样在我命名为“WikimediaAPI”的单独文件中)如下所示:
public func getThumbnailImage(forPage page: String) -> UIImage? {
if let data = try? Data(contentsOf: URL(string: "https://en.wikipedia.org/w/api.php?action=query&titles=" + page + "&prop=pageimages&format=json&pithumbsize=1000")!) {
let json = JSON(data: data)
if let pageId = json["query"]["pages"].dictionary?.first?.key {
if let imageUrl = json["query"]["pages"][pageId]["thumbnail"]["source"].string {
if let url = URL(string: imageUrl) {
if let imageData = try? Data(contentsOf: url) {
if let image = UIImage(data: imageData) {
return image
}
}
}
}
}
}
return nil
}
上述代码可行,但是不支持多线程,当我从表视图控制器切换到此视图控制器时,时间太长。我尝试按照以下方式实现多线程,但是我无法在异步块中返回任何内容。
public func getThumbnailImage(forPage page: String) -> UIImage? {
DispatchQueue.global().async {
if let data = try? Data(contentsOf: URL(string: "https://en.wikipedia.org/w/api.php?action=query&titles=" + page + "&prop=pageimages&format=json&pithumbsize=1000")!) {
DispatchQueue.main.async {
let json = JSON(data: data)
if let pageId = json["query"]["pages"].dictionary?.first?.key {
if let imageUrl = json["query"]["pages"][pageId]["thumbnail"]["source"].string {
if let url = URL(string: imageUrl) {
DispatchQueue.global().async {
if let imageData = try? Data(contentsOf: url) {
DispatchQueue.main.async {
if let image = UIImage(data: imageData) {
return image //error: "Unexpected non-void return value in void function"
}
}
}
}
}
}
}
}
}
}
return nil
}
我曾经考虑过在异步代码块中返回闭包,而不是UIImage,但我不确定如何实现。如果这样做,我仍然需要在视图控制器中设置图像,这一点我也不确定该怎么做。
以下是在视图控制器中调用该函数的代码:
let wikiQuery = WikimediaAPI() // the class from above
fileprivate func setImage() {
if let pageTitle = wikimediaPageTitleDict[(allergy.0).lowercased()] {
if let image = wikiQuery.getThumbnailImage(forPage: pageTitle) {
wikipediaImage.image = image
wikipediaImage.contentMode = .scaleAspectFit
}
}
}
我正在使用一个字典(wikimediaPageTitleDict)从plist文件中将字符串与正确的维基百科页面(allergy.0是该字符串)关联起来。
感谢任何帮助。谢谢!
if let
链接到同一条件中,以避免死亡金字塔。 - JAL