使用新游标多次执行 CKQueryOperation
Posted
技术标签:
【中文标题】使用新游标多次执行 CKQueryOperation【英文标题】:Executing a CKQueryOperation multiple times with a new cursor 【发布时间】:2015-08-24 19:02:34 【问题描述】:我有一个CKQueryOperation
处理一千条记录,因此我需要多次执行该操作。我尝试更改光标并添加如下代码中的操作:
let queryOperation = CKQueryOperation(query: query)
queryOperation.recordFetchedBlock = (rule: CKRecord) in
print(rule)
queryOperation.database = publicDB
queryOperation.queryCompletionBlock = (cursor : CKQueryCursor?, error : NSError?) in
if error != nil
print(error?.localizedFailureReason)
else
if cursor != nil // The cursor is not nil thus we still have some records to download
queryOperation.cursor = cursor
queue.addOperation(queryOperation)
else
print("Done")
// Creation of the dependent operation secondQueryOperation
queue.addOperations([queryOperation, secondQueryOperation], waitUntilFinished: true)
运行时崩溃并返回[NSOperationQueue addOperation:]: operation is executing and cannot be enqueued
。我能做什么?之后我还有其他操作依赖于这个 queryOperation,所以我需要在启动其他 CKOperation
s 之前正确命中。
【问题讨论】:
如何初始化 secondQueryOperation ? 正常初始化一个NSQueryOperation
然后secondQueryOperation.addDependency(queryOperation)
【参考方案1】:
您应该创建一个新操作,而不是再次执行相同的操作。下面你可以看到来自EVCloudKitDao的代码sn-p,看看它是如何使用的。
internal func queryRecords<T:EVCloudKitDataObject>(type:T, query: CKQuery, completionHandler: (results: [T]) -> Bool, errorHandler:((error: NSError) -> Void)? = nil)
if !(query.sortDescriptors != nil)
query.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
let operation = CKQueryOperation(query: query)
var results = [T]()
operation.recordFetchedBlock = record in
if let parsed = self.fromCKRecord(record) as? T
results.append(parsed)
operation.queryCompletionBlock = cursor, error in
self.handleCallback(error, errorHandler: errorHandler, completionHandler:
if completionHandler(results: results)
if cursor != nil
self.queryRecords(cursor!, continueWithResults: results, completionHandler: completionHandler, errorHandler: errorHandler)
)
operation.resultsLimit = CKQueryOperationMaximumResults;
database.addOperation(operation)
private func queryRecords<T:EVCloudKitDataObject>(cursor: CKQueryCursor, continueWithResults:[T], completionHandler: (results: [T]) -> Bool, errorHandler:((error: NSError) -> Void)? = nil)
var results = continueWithResults
let operation = CKQueryOperation(cursor: cursor)
operation.recordFetchedBlock = record in
if let parsed = self.fromCKRecord(record) as? T
results.append(parsed)
operation.queryCompletionBlock = cursor, error in
self.handleCallback(error, errorHandler: errorHandler, completionHandler:
if completionHandler(results: results)
if cursor != nil
self.queryRecords(cursor!, continueWithResults: results, completionHandler: completionHandler, errorHandler: errorHandler)
)
operation.resultsLimit = CKQueryOperationMaximumResults;
database.addOperation(operation)
【讨论】:
只是一个小建议,在用光标安排下一个操作之前检查!results.isEmpty
是否。当resultsLimit
恰好小于记录数时,有时即使获取了所有记录,也会返回游标。我认为这是CloudKit
的错误,最好使用!results.isEmpty
进行检查,这样我们就不会无限期地继续查询以上是关于使用新游标多次执行 CKQueryOperation的主要内容,如果未能解决你的问题,请参考以下文章