objective c - CKQueryOperation working with big batch -
i have problem creating ckquery operation big batch of data. query works 100 results after more results query fail, because 1 thread bad dispatched or (libdispatch.dylib`dispatch_group_leave: ) lost... idea?
+ (void) fetchanswerswithrecordid:(ckrecordid *)recordid completionhandler:(cloudkitcompletionhandler)handler { nspredicate *predicate = [nspredicate predicatewithformat:@"ansrecordid == %@", recordid]; ckquery *query = [[ckquery alloc] initwithrecordtype:ckanswers predicate:predicate]; ckqueryoperation *operation = [[ckqueryoperation alloc] initwithquery:query]; ckqueryoperation * __weak weakself = operation; operation.resultslimit = 300; nsmutablearray *tmp = [[nsmutablearray alloc] init]; operation.recordfetchedblock = ^(ckrecord *record) { [tmp addobject:record]; }; operation.querycompletionblock = ^(ckquerycursor *cursor, nserror *error) { if (!handler) return; nsarray *array = [nsarray arraywitharray:tmp]; if(cursor != nil) { ckqueryoperation *newoperation = [[ckqueryoperation alloc] initwithcursor:cursor]; newoperation.recordfetchedblock = weakself.recordfetchedblock; newoperation.completionblock = weakself.completionblock; [[self publicclouddatabase] addoperation:newoperation]; } else { nslog(@"results: %lu", [array count]); dispatch_async(dispatch_get_main_queue(), ^{ handler(array, error); }); } }; [[self publicclouddatabase] addoperation:operation];}
i think issue lies __weak operation , way create operation inside operation. here example (in swift) of how similar i.e. additional results, in fetch , not query. note use of instance variable initialize first time , use of semi-recursion through gcd dispatch_aync:
private func _fetchrecordchangesfromcloud() { if !_fetching { // first , time code called in gcd recusion // clean caches use collect results of fetch // can save record in correct order references can created _fetchedmodifiedrecords = [] _fetcheddeletedrecordids = [] // mark fetching has started _fetching = true } let operation = ckfetchrecordchangesoperation(recordzoneid: _customrecordzoneid, previousserverchangetoken: _serverchangetoken) operation.recordchangedblock = { (record: ckrecord?) in if let record = record { println("received record save: \(record)") self._fetchedmodifiedrecords.append(record) } } operation.recordwithidwasdeletedblock = { (recordid: ckrecordid?) in if let recordid = recordid { println("received recordid delete: \(recordid)") self._fetcheddeletedrecordids.append(recordid) } } operation.fetchrecordchangescompletionblock = { (serverchangetoken: ckserverchangetoken?, clientchangetoken: nsdata?, error: nserror?) -> void in if let error = error { println("error in fetching record changes: \(error)") // try again next sync self._fetchafternextsuccessfullsync = true self._fetching = false return } // fetched records successfuly println("fetched records successfuly") if let serverchangetoken = serverchangetoken { self._serverchangetoken = serverchangetoken } if operation.morecoming { // need create operation object , again dispatch_async(dispatch_get_global_queue(dispatch_queue_priority_default, 0)) { self._fetchrecordchangesfromcloud() } } else { // done // process fetched records self._processfetchedrecords() // save changes persistent store self._savebackgroundcontext() // done self._fetching = false } } self._privatedatabase.addoperation(operation) }
Comments
Post a Comment