CloudKit - 每次运行相同的查询时,CKQueryOperation 结果都不同

Posted

技术标签:

【中文标题】CloudKit - 每次运行相同的查询时,CKQueryOperation 结果都不同【英文标题】:CloudKit - CKQueryOperation results different each time the same query is ran 【发布时间】:2015-06-30 07:34:54 【问题描述】:

就是这种情况 - 我正在使用一个简单的 UITableView 来呈现来自 CloudKit publicDB 的记录。当我运行应用程序时,查询操作返回例如返回 2 个结果(这就是它目前的全部)。

我的表格视图有一个刷新控件,当我拉动刷新时,结果为零,如果我继续重新加载,最终可能会出现结果,但现在总是这样。

同样的事情也会发生更多的结果,我曾经有我查询过的 CKLocation 类型并且响应总是不同的,没有任何常识

一些示例代码(本例中的谓词是 TRUEPREDICATE - 没什么特别的):

    let sort = NSSortDescriptor(key: "creationDate", ascending: false)        
    let query = CKQuery(recordType: "Tests", predicate: DiscoveryMode.getPredicate())
    query.sortDescriptors = [sort]

    var operation = CKQueryOperation(query: query)
    if lastCursor != nil 
        operation = CKQueryOperation(cursor: lastCursor)
    

    operation.resultsLimit = 15
    operation.recordFetchedBlock = recordFetchBlock
    operation.queryCompletionBlock =  [weak self] (cursor:CKQueryCursor!, error:NSError!) in

        if cursor != nil 
             self!.lastCursor = cursor
        

        dispatch_async(dispatch_get_main_queue(),  () -> Void in

            Misc.hideLoadingInView(view: self!.view)

            self!.tableView.reloadData()
            self!.refreshControl.endRefreshing()

            if error != nil 
                Misc.showErrorInView(view: self!.view, message: error.localizedDescription)
            
        )
    

    CloudKit.sharedInstance.publicDB.addOperation(operation)

recordFetchBlock 所做的只是将对象添加到表视图用作数据源的可变数组中。

我是 CloudKit 的新手,我很困惑这是设计使然(不是返回所有结果,而是返回一些随机结果)还是我做错了什么?

【问题讨论】:

【参考方案1】:

我看到您正在使用光标。因此,第二次通话将从第一次通话结束的地方开始。您的 resultsLimit 为 15。使用游标时,如果记录超过 15 条,您将仅在第二次执行查询时收到记录。要测试这是否是问题,只需注释掉设置光标的行: operation = CKQueryOperation(cursor: lastCursor)

【讨论】:

嗯,有趣,afaik 只有当结果超过提供的限制时才会返回光标。我从没想过会出现这种情况(没有调试光标),按照你的建议做了,现在它看起来像在工作......很奇怪......如果那个光标检查不可信,我怎么知道有超过限制的结果? 嗯,不,还有问题……不是光标 啊..你是对的...光标应该是nil...但是您仍然应该始终将其设置为queryCompletionBlock中的返回值。否则它永远不会回到 nil 并继续从前一个光标重新开始(如果有) 看起来这是带有 CLLocation 谓词的东西:CURSOR: nil PREDICATE: distanceToLocation:fromLocation:(location, <+42.68164669,+23.31165791>) < 500 - record with distance = 0.427553534524166 km. - record with distance = 0.427553534524166 km. CURSOR: nil PREDICATE: distanceToLocation:fromLocation:(location, <+42.67792387,+23.29822540>) < 500 - record with distance = 1.34367205197676 km. - record with distance = 1.34367205197676 km. CURSOR: nil PREDICATE: distanceToLocation:fromLocation:(location, <+42.66631226,+23.28874111>) < 500 ??? - no records 但您的位置不同。我认为您的记录将位于您的选择之外。当您将选择增加到 5000 个时会发生什么?【参考方案2】:

我发现了这个问题,我试图(在 NSPredicate 中)一个半径,我在某处读取的值以公里为单位。因此,我试图查询 500 米而不是 500 公里内的记录,并且我在模拟器中使用的 GPX 文件有多个距离较远的记录。由于它模拟运动,因此无法获得一致的结果。

现在,当我使用适当的半径值时,一切似乎都很好!

【讨论】:

以上是关于CloudKit - 每次运行相同的查询时,CKQueryOperation 结果都不同的主要内容,如果未能解决你的问题,请参考以下文章

查询每次运行都返回相同的数据

使用子查询提取随机值每次都显示相同的值

每次使用不同的参数运行相同的 mysqli 查询

CloudKit 在 App Store 部署后不再工作

为啥我不能从 Xcode 或 CloudKit Dashboard 查询 CloudKit?

在 Google Apps 脚本中使用 CloudKit Web 服务 API 查询 CloudKit 公共数据库时的 AUTHENTICATION_FAILED