CKQueryOperation queryCompletionBlock只运行3次

Osw*_*ldt 8 macos swift cloudkit

我正在尝试使用CloudKit和光标从我的iCloud公共数据库下载一批记录.无论resultLimit如何设置,代码都可以在前3次执行中正常工作,但是从不执行第4个完成块.如果没有设置resultsLimit我得到300条记录,如果它设置为50我得到150,如果它设置为5我得到15 ...

没有报告错误,该块似乎已添加,但从未执行过.平台是OS X.以下是有问题的代码:

        let queryOp = CKQueryOperation(query: query)
        queryOp.recordFetchedBlock = self.fetchedDetailRecord
        queryOp.resultsLimit = 5
        queryOp.queryCompletionBlock = { [weak self]
          (cursor: CKQueryCursor!, error: NSError!) -> Void in
          println("comp block called with \(cursor) \(error)")
          if error != nil {
            println("Error on fetch \(error.userInfo)")
          } else {
            if cursor != nil {
              let nextOp = CKQueryOperation(cursor: cursor)
              nextOp.recordFetchedBlock = self!.fetchedDetailRecord
              nextOp.queryCompletionBlock = queryOp.queryCompletionBlock
              nextOp.resultsLimit = 5
              self!.publicDatabase?.addOperation(nextOp)
              println("added next fetch")
            } else {
              self!.fileHandle!.closeFile()
              self!.exportProgressIndicator.stopAnimation(self)
            }
          }
        }

        self.publicDatabase?.addOperation(queryOp)
Run Code Online (Sandbox Code Playgroud)

这是控制台的结果 -

459013587628.012 0 459013587628.621 1 459013587628.863 2 459013587629.113 3 459013587629.339 4比较块称为与下一个加零取称为与下一个加零459013587828.552 5 459013587828.954 6 459013587829.198 7 459013587829.421 8 459013587829.611 9排版块取459013587997.084 10 459013587997.479 11 459013587997.74 12 459013587997.98 13 459013587998.207 14

大数字只是对recordFetchedBlock的调用之间的时间,第二个数字是调用该块的次数.

我很难过......关于如何进行的任何想法?哦,container和publicDatabase是类变量,并在运行上面的代码片段之前进行了初始化.

Dav*_*ing 6

您在queryCompletionBlock范围内定义nextOp的方式在该块的三次迭代后导致问题.如果你将CKQueryOperation的创建分解为自己的方法,你的问题就会消失.

这是代码:

func fetchedDetailRecord(record: CKRecord!) -> Void {
    println("Retrieved record: \(record)")
}

func createQueryOperation(cursor: CKQueryCursor? = nil) -> CKQueryOperation {
    var operation:CKQueryOperation
    if (cursor != nil) {
        operation = CKQueryOperation(cursor: cursor!)
    } else {
        operation = CKQueryOperation(query: CKQuery(...))
    }
    operation.recordFetchedBlock = self.fetchedDetailRecord
    operation.resultsLimit = 5
    operation.queryCompletionBlock = { [weak self]
        (cursor: CKQueryCursor!, error: NSError!) -> Void in
        println("comp block called with \(cursor) \(error)")
        if error != nil {
            println("Error on fetch \(error.userInfo)")
        } else {
            if cursor != nil {
                self!.publicDatabase?.addOperation(self!.createQueryOperation(cursor: cursor))
                println("added next fetch")
            } else {
                self!.fileHandle!.closeFile()
                self!.exportProgressIndicator.stopAnimation(self) 
            }
        }
    }
    return operation
}

func doQuery() {
    println("Querying records...")
    self.publicDatabase?.addOperation(createQueryOperation())
}
Run Code Online (Sandbox Code Playgroud)

  • 谢谢!但是,似乎operation.cursor = cursor不会使操作以光标开始; 而是使用operation = CKQueryOperation(cursor:cursor)为我工作 - 想法? (2认同)

car*_*ine 6

这可能是另一种方法(已更新到 Swift 3)。

第三次迭代后不会停止,而是一直持续到结束

var queryOp = CKQueryOperation(query: query)
queryOp.recordFetchedBlock = self.fetchedARecord
queryOp.resultsLimit = 5
queryOp.queryCompletionBlock = { [weak self] (cursor : CKQueryCursor?, error : Error?) -> Void in
    print("comp block called with \(cursor) \(error)")

    if cursor != nil {
        let nextOp = CKQueryOperation(cursor: cursor!)
        nextOp.recordFetchedBlock = self!.fetchedARecord
        nextOp.queryCompletionBlock = queryOp.queryCompletionBlock
        nextOp.resultsLimit = queryOp.resultsLimit

        //this is VERY important
        queryOp = nextOp

        self!.publicDB.add(queryOp)
        print("added next fetch")
    }

}

self.publicDB.add(queryOp)
Run Code Online (Sandbox Code Playgroud)

我成功地用它从 CloudKit 中检索了数百条记录