使用新游标多次执行 CKQueryOperation
Executing a CKQueryOperation multiple times with a new cursor
我有一个 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)
当 运行 它崩溃并且 returns [NSOperationQueue addOperation:]: operation is executing and cannot be enqueued
。我能做什么?在那之后我还有其他操作依赖于这个 queryOperation 所以我需要在开始其他 CKOperation
s 之前正确命中。
您应该创建一个新操作,而不是再次执行相同的操作。您可以在下面看到来自 EVCloudKitDao 的代码片段,了解如何使用它。
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)
}
我有一个 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)
当 运行 它崩溃并且 returns [NSOperationQueue addOperation:]: operation is executing and cannot be enqueued
。我能做什么?在那之后我还有其他操作依赖于这个 queryOperation 所以我需要在开始其他 CKOperation
s 之前正确命中。
您应该创建一个新操作,而不是再次执行相同的操作。您可以在下面看到来自 EVCloudKitDao 的代码片段,了解如何使用它。
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)
}