如何确定何时从 Swift 中的集合中下载了所有图像?

Posted

技术标签:

【中文标题】如何确定何时从 Swift 中的集合中下载了所有图像?【英文标题】:How to determine when all images have been downloaded from a set in Swift? 【发布时间】:2016-03-01 04:24:56 【问题描述】:

我正在使用 PinRemoteImage 库下载填充 collectionView 的图像。我想根据图像高度动态更新单元格高度,所以我需要知道我的所有图像何时下载,以便我可以重新加载/使我的collectionViewLayout 无效。确定何时没有更多图像可供下载的最佳方法是什么?

override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell 

        let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! PinCollectionViewCell

       cell.pinImage?.pin_updateWithProgress = true
       cell.pinImage?.image = nil

        if let pinImageURL = self.pins[indexPath.row].largestImage().url 


            cell.pinImage?.pin_setImageFromURL(pinImageURL, completion: ( (result : PINRemoteImageManagerResult) -> Void in

                if let image = result.image 
                    self.imageArray.append(image)

                

【问题讨论】:

只需检查 imageArray 的count 是否与completion 块中self.pinscount 相同。如果是,那就意味着他们都完成了。 不要在尝试显示时执行 URL 请求,您需要在尝试显示之前执行该请求。要回答您的问题,您需要查看完成处理程序。祝你好运 你真的需要等到一切都归还了吗?如果您返回 99 但有一次失败怎么办?每次返回时更新显示,并为用户提供逐渐改进的显示会更好吗? @Russell 好点,我想这是我要走的方向,谢谢指出。 【参考方案1】:

我从未使用过 PinRemoteImage 图像库,但是当您从 iCloud 下载不起作用时回复完成块,导致愚蠢的进程背景,然后在它下载所有数据之前触发您的完成子句。这是我需要实现的 CloudKit 代码的摘录。

它使用的是 NSOperationalQueue,代码在这里。警告如果您的任何图像下载失败,此代码将进入无限循环,最好的情况是创建僵尸,最坏的情况是停止您的应用程序。

注意 self.filesQ.returnQThumbs 是一个子程序,它检查下载的图像的大小,如果它们大于零,则为 1,如果它们为 0/nil,则仍在下载...它返回找到的数字数组。 self.filesQ.qcount() 返回它要下载的图像数量。

func preThumb() 

    newQueue = NSOperationQueue()

    let operation2 = NSBlockOperation(block: 
        print("Downloaded, you can now use")
    )

    operation2.completionBlock = 
        print("Operation 2 completed")
    

    let operation1 = NSBlockOperation(block: 
        var allclear = 0


        while (allclear != self.filesQ.qcount()) 
            allclear = self.filesQ.returnQThumbs().count
        
    )

    operation1.completionBlock = 
        print("Operation 1 completed") 

        // your code to display images could go here!

        self.newQueue.addOperation(operation2)
    

    operation1.qualityOfService  = .Background
    newQueue.addOperation(operation1)

显然,在理想情况下,您可能不需要在开始下载之前运行此方法。

【讨论】:

我不确定我是否遵循,您的业务逻辑在哪里?即实际下载的方法与 operation1 和 operation2 有什么关系? Gary,它们并行运行。您启动 operation1 循环,直到下载所有图像,完成后启动操作 2。与此同时,您的下载在其自己的线程上运行。您可以在您的情况下跳过 operation2 并在 operation1 的完成阶段显示图像。 谢谢,我的意思是我的 cell.pinImage?.pin_setImageFromURL 方法会进入 operation1 的块吗?

以上是关于如何确定何时从 Swift 中的集合中下载了所有图像?的主要内容,如果未能解决你的问题,请参考以下文章

Swift 3:如何确定下载文件的网速?

Swift 3.0 中的 Spotify SDK:如何知道歌曲何时结束

如何在 Swift 中的集合视图上方添加水平按钮堆栈?

如何判断所有可见图块何时已满载?

如何从 Swift 中的远程目录中获取所有图像?

如何在 Swift Firebase 中更新一个集合中的所有文档