来自 CKAsset 的图像在 Swift 中乱序加载

Posted

技术标签:

【中文标题】来自 CKAsset 的图像在 Swift 中乱序加载【英文标题】:Images from CKAsset Load Out of Order in Swift 【发布时间】:2016-04-23 15:57:55 【问题描述】:

我正在加载从公共 CloudKit 数据库作为 CKAsset 获取的图像的表格视图。但是,在将正确的图像加载到自定义 UITableview 单元格的 UIImageView 之前,图像会乱序加载大约两秒钟。我知道问题在于,由于单元格是可重复使用的,因此图像仍然从 CloudKit 下载并显示在任何可见的单元格中,而用户在正确的图像显示在图像视图中之前滚动 TableView 时。我想知道是否有快速解决此问题的方法,以便下载的图像仅适用于可见单元格的图像,而不适用于任何以前的单元格。

这是 cellForRowAtIndexPath 的代码:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 
    let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! PostsTableViewCell
    cell.userInteractionEnabled = false

    photoRecord = sharedRecords.fetchedRecords[indexPath.row]

    cell.photoTitle.text = photoRecord.objectForKey("photoTitle") as? String

    cell.photoImage.backgroundColor = UIColor.blackColor()
    cell.photoImage.image = UIImage(named: "stock_image.png")

    if let imageFileURL = imageCache.objectForKey(self.photoRecord.recordID) as? NSURL 
        cell.photoImage.image = UIImage(data: NSData(contentsOfURL: imageFileURL)!)
        cell.userInteractionEnabled = true
        print("Image Cached: \(indexPath.row)")
     else 

        let container = CKContainer.defaultContainer()
        let publicDatabase = container.publicCloudDatabase
        let fetchRecordsImageOperation = CKFetchRecordsOperation(recordIDs:[self.photoRecord.recordID])
        fetchRecordsImageOperation.desiredKeys = ["photoImage"]
        fetchRecordsImageOperation.queuePriority = .VeryHigh

        fetchRecordsImageOperation.perRecordCompletionBlock = (record:CKRecord?, recordID:CKRecordID?, error:NSError?) -> Void in
            if let imageRecord = record 
                NSOperationQueue.mainQueue().addOperationWithBlock() 
                    if let imageAsset = imageRecord.objectForKey("photoImage") as? CKAsset
                        cell.photoImage.image = UIImage(data: NSData(contentsOfURL: imageAsset.fileURL)!)
                        self.imageCache.setObject(imageAsset.fileURL, forKey:self.photoRecord.recordID)
                        cell.userInteractionEnabled = true
                        
                    
                
            
        publicDatabase.addOperation(fetchRecordsImageOperation)
        
    return cell

提前致谢!

【问题讨论】:

【参考方案1】:

在您的表格视图出现和调用fetchRecordsImageOperation.perRecordCompletionBlock 之间存在延迟。在这段时间内,如果您不检查单元格的索引路径是否与您构造时相同 fetchRecordsImageOperation.perRecordCompletionBlock ,这一行:cell.photoImage.image = UIImage(data: NSData(contentsOfURL: imageAsset.fileURL)!) 将导致图像被放置在已经显示不同数据的单元格中。您可以像这样修改完成块以避免这种情况。

if let imageRecord = record 
                NSOperationQueue.mainQueue().addOperationWithBlock() 
                    if let imageAsset = imageRecord.objectForKey("photoImage") as? CKAsset
                        if indexPath == tableView.indexPathForCell(cell)
                            cell.photoImage.image = UIImage(data: NSData(contentsOfURL: imageAsset.fileURL)!)
                        
                        self.imageCache.setObject(imageAsset.fileURL, forKey:self.photoRecord.recordID)
                        cell.userInteractionEnabled = true
                        
                    
                

【讨论】:

这正是我所需要的!我当时认为这是问题所在,但我不太确定在 cellForRowAtIndexPath 中的何处实施该解决方案。再次感谢!【参考方案2】:

我相信你在这里找到了答案,我当然有偏见,因为我写了它。

How to determine when all images have been downloaded from a set in Swift?

您应该设置在加载图像时显示的图像并显示它以便用户了解正在发生的事情?

【讨论】:

以上是关于来自 CKAsset 的图像在 Swift 中乱序加载的主要内容,如果未能解决你的问题,请参考以下文章

Swift 3 使用 CKAsset 将图像发送到 CloudKit

您如何处理消息队列中乱序的消息?

fluentd 丢失毫秒,现在日志消息在 elasticsearch 中乱序存储

CKAsset 获取 PDF 并呈现在 UIWebView Swift3 中

在 CloudKit 中将图像存储为 CKAsset,图像倒置

CKAsset 不会显示在 tableview 图像中