我知道这类问题已经被问过17次了,但我遇到了一个我认为没有涉及到的具体问题/这是显而易见的,但我太新手了,无法自己解决。
在acellForRowAt
中的TableViewController
方法中有以下代码片段:
let currentDictionary = parser.parsedData[indexPath.row] as Dictionary<String,String>
let urlString = currentDictionary["media:content"]
if urlString != nil {
let url = NSURL(string: urlString!)
DispatchQueue.global().async {
let data = try? Data(contentsOf: url! as URL) //make sure your image in this url does exist, otherwise unwrap in a if let check / try-catch
DispatchQueue.main.async {
cell.thumbnailImageView.image = UIImage(data: data!)
}
}
}
它执行良好,下载图像并将它们分配给每个
UIImageView
的tableViewCell
。可以说,当图像“动态”下载时,滚动表格会有有限的延迟。
我想做的是预先下载所有这些图片,并将它们保存在一个数据结构中,这样它们就不会频繁地从URL获取。
我尝试了以下实现:
var thumbnail = UIImage()
for item in parser.parsedData {
let currentDictionary = item as Dictionary<String,String>
let title = currentDictionary["title"]
let link = currentDictionary["link"]
let urlString = currentDictionary["media:content"]
let url = NSURL(string: urlString!)
if urlString != nil {
let url = NSURL(string: urlString!)
DispatchQueue.global().async {
let data = try? Data(contentsOf: url! as URL)
DispatchQueue.main.sync {
thumbnail = UIImage(data: data!)!
}
}
}
var newsArticle: News!
newsArticle = News(title: title!, link: link!, thumbnail: thumbnail)
news.append(newsArticle)
新闻是我的数据结构。这段代码也执行得很好,但是根据控制台的输出,每个缩略图都是一个0x0大小的图像,大小{0,0}方向0比例1.000000。
是否有人知道如何下载这些图像,但不立即将其分配给
UIImageView
,而是将其存储以备以后使用? 最佳答案
问题是,您甚至在全局调度队列开始处理您的newsArticle
之前就创建了url
。因此,thumbnail
仍然是第一行中创建的空UIImage()
。
您必须在内部分派闭包中创建缩略图,例如:
for item in parser.parsedData {
guard let currentDictionary = item as? Dictionary<String,String> else { continue /* or some error handling */ }
guard let title = currentDictionary["title"] else { continue /* or some error handling */ }
guard let link = currentDictionary["link"] else { continue /* or some error handling */ }
guard let urlString = currentDictionary["media:content"] else { continue /* or some error handling */ }
guard let url = URL(string: urlString) else { continue /* or some error handling */ }
DispatchQueue.global().async {
if let data = try? Data(contentsOf: url) {
DispatchQueue.main.sync {
if let thumbnail = UIImage(data: data) {
let newsArticle = News(title: title, link: link, thumbnail: thumbnail)
news.append(newsArticle)
}
}
}
}
}
顺便说一下,您的第一个代码(
cellForRow...
)也被破坏了:您不能引用dispatch闭包中的单元格:DispatchQueue.main.async {
// Never do this
cell.thumbnailImageView.image = UIImage(data: data!)
}
相反,引用
IndexPath
,检索clousure中的单元格,然后继续使用该单元格。但是正如您已经提到的,stackoverflow上有很多关于这个问题的条目。关于ios - Swift Grand Central调度队列和UIImages,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50249992/