Swift Grand Central Dispatch队列和UIImages

时间:2018-05-09 09:32:04

标签: ios swift uiimageview grand-central-dispatch

我知道这类问题已经被问过1次,但是我遇到了一个我认为没有被覆盖的特定问题/明显很明显,但我太过新手无法自行解决。< / p>

我在cellForRowAt的{​​{1}}方法中有以下代码段:

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!) } } } 的{​​{1}}。

滚动表格时有一个有限的延迟,因为图像是在飞行中下载的。可以这么说。

我想要做的是预先下载所有这些图片并将其保存在数据结构中,这样就可以不那么频繁地从网址中提取这些图片。

我尝试了以下实现:

UIImageView

新闻是我的数据结构。此代码也可以正常执行,但根据控制台输出,每个缩略图都是0x0大小的图像,大小为{0,0}方向0缩放1.000000。

有没有人有任何想法如何下载这些图片,但没有立即将它们分配给tableViewCell,而是存储它们供以后使用?

1 个答案:

答案 0 :(得分:1)

问题是您在全局调度队列开始处理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...)也被破坏了:你不能引用调度闭包中的单元格:

DispatchQueue.main.async {
    // Never do this
    cell.thumbnailImageView.image = UIImage(data: data!)
} 

相反,引用IndexPath,检索clousure中的单元格,然后继续使用该单元格。但正如您已经提到的,关于此问题,stackoverflow上有许多条目。