DispatchQueue.main.async阻塞主线程

时间:2018-11-03 04:32:56

标签: ios swift uicollectionview

我一直试图在Swift 3.0中创建一个图片库,我想将文档目录中存储的图像异步加载到集合视图中。我尝试了DispatchQueue.main.async,但是它阻塞了主线程并冻结了应用几秒钟:

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let identifier = "ImageCell"
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: identifier, for: indexPath) as! ImageCell
    let url = self.imageURL[indexPath.row]
    cell.lazyLoadImage(from: url)
    return cell
}

还有ImageCell类:

class ImageCell: UICollectionViewCell {
    @IBOutlet weak var imageView: UIImageView!

    func lazyLoadImage(from url: URL) {
        DispatchQueue.main.async {
            if let image = UIImage(contentsOfFile: url.path) {
                self.imageView.image = image
            }
        }
    }
}

感谢您的帮助。谢谢。

2 个答案:

答案 0 :(得分:1)

首先切换到后台线程并在其上加载图像,然后再次切换到主线程并显示图像。

func lazyLoadImage(from url: URL) {
     DispatchQueue.global(qos: .userInteractive).async {
         if let image = UIImage(contentsOfFile: url.path) {
             DispatchQueue.main.async {
                 self.imageView.image = image
             }
         }
    }
}

答案 1 :(得分:0)

您正在完成错误。简而言之,我可以说这不是“延迟加载”。您正在执行的操作是阻止线程从URL下载内容并将其加载到UIImageView。直到下载完成并且您在“可重用单元”中使用该线程后,该线程才会被释放,很明显您的应用程序将卡住!

  

解决方案

有许多最受欢迎的库,例如AlamofireImageSDWebImageKingfisher。我从中拾取“ SDWebImage”,然后可以通过以下代码以async的方式调用加载图像:

imageView.sd_setImage(with: url , placeholderImage: nil)

另外,请参阅此SO问题(how to implement lazy loading of images in table view using swift),以获取更多详细信息。