首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从CKAsset中提取CloudKit图像非常缓慢

从CKAsset中提取CloudKit图像非常缓慢
EN

Stack Overflow用户
提问于 2016-02-17 05:01:27
回答 2查看 2.8K关注 0票数 11

我正在使用CloudKit作为iOS应用程序的服务器后端。我用它来存放一些相对静态的数据以及一些图像(CKAsset)。当我真正从公共数据库中获取这些资产的时候,我遇到了一个问题。它们以极慢的速度装载。

我的用例是将图像加载到集合视图中的每个单元格中。这些图像只有200 in大小,但是下载完成并在一个单元格中设置图像平均需要2.2秒。为了进行比较,我使用了类似大小的股票映像的URL,并使用NSURLSession加载它们。加载每幅图像只需0.18-0.25秒。

我尝试过从CK下载图像的多种不同方法:直接获取记录、查询和操作查询。他们都有相似的结果。在为单元格设置映像之前,我还将返回到完成块中的主队列。

我的数据库设置为具有多个数据字段的主对象。然后,我为这些照片设置了一个反向引用样式系统,其中每一张照片都有一个对主对象的引用。这样,我就可以按需加载照片,而不必纠缠于主要数据。

看起来是这样的:

主对象: title: String, startDate: Date

图片对象: owner: String(reference to primary object), image: Asset

下面是我试图直接获取其中一张照片的示例请求:

代码语言:javascript
复制
let publicDb = CKContainer.defaultContainer().publicCloudDatabase
let configRecordId = CKRecordID(recordName: "e783f542-ec0f-46j4-9e99-b3e3ez505adf")

publicDb.fetchRecordWithID(configRecordId) { (record, error) -> Void in
    dispatch_async(dispatch_get_main_queue()) {
        guard let photoRecord = record else { return }
        guard let asset = photoRecord["image"] as? CKAsset else { return }

        guard let photo = NSData(contentsOfURL: asset.fileURL) else { return }

        let image = UIImage(data: photo)!

        cell.cardImageView.image = image
    }
}

我似乎不知道为什么这些图像下载要花这么长时间,但如果我不能让它们在合理的时间内加载的话,这确实是一个很好的表现。

更新:我尝试了一个较小的图像,23 the的获取操作。抓取速度更快,从0.3秒到1.1秒不等.这样做更好,但仍然没有达到我对CloudKit所能提供的东西的期望。

EN

回答 2

Stack Overflow用户

发布于 2016-05-01 12:23:49

我正在使用CKQueryOperation。我发现,一旦我在代码中添加了下面一行,下载CKAssets的速度就提高了大约5-10倍。

代码语言:javascript
复制
    queryOperation.qualityOfService = .UserInteractive

这是我的完整代码:

代码语言:javascript
复制
func getReportPhotos(report:Report, completionHandler: (report:Report?, error:NSError?) -> ()) {
    let photo : Photo = report.photos![0] as! Photo
    let predicate : NSPredicate = NSPredicate(format: "recordID = %@", CKRecordID(recordName: photo.identifier!))
    let query : CKQuery = CKQuery(recordType: "Photo", predicate: predicate)
    let queryOperation : CKQueryOperation = CKQueryOperation()
    queryOperation.query = query
    queryOperation.resultsLimit = numberOfReportsPerQuery        
    queryOperation.qualityOfService = .UserInteractive
    queryOperation.recordFetchedBlock = { record in
        photo.date = record.objectForKey("date") as? NSDate
        photo.fileType = record.objectForKey("fileType") as? String
        let asset : CKAsset? = record.objectForKey("image") as? CKAsset
        if asset != nil {
            let photoData : NSData? = NSData(contentsOfURL:asset!.fileURL)
            let photo : Photo = report.photos![0] as! Photo
            photo.image = UIImage(data:photoData!)
        }

    }
    queryOperation.queryCompletionBlock = { queryCursor, error in
        dispatch_async(dispatch_get_main_queue(), {
            completionHandler(report: report, error: error)
        })
    }
    publicDatabase?.addOperation(queryOperation)
}
票数 7
EN

Stack Overflow用户

发布于 2016-03-06 14:51:53

在执行dispatch_async调用的捕获块时,似乎有一些东西减慢了您的主线程。您的代码是否可能并行多次调用此记录获取函数?这将导致NSData(contentsOfURL: asset.fileURL)处理占用主线程并引入累积延迟。

在任何情况下,如果只是作为一个良好的实践,使用NSData加载图像应该在后台执行,而不是在主线程上执行。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35448287

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档