ios - Cancel PFQuery takes too much time to load -
apologies couldn't think of better way describe application’s functionality.
i've found quite lot of posts topic, in old archive @ parse.com. nevertheless doesn't work me. after creating instance of pfquery triggered pfquery.findobjects (but runs on background thread) i'm not able cancel during request process.
scenario : have app connects parse. have display data more 100 records in datadisplay screen , has button when user click on button , if pfquery.findobjects still run on background thread have cancel it.
i have tried inserting pfquery.cancel in viewwilldisappear, can not stop , due these datadisplay screen’s dealloc method not call.
my code, incase may help:
- (void)loadandsortingsonginformationws { if(isinternet) { if(self.isshowloadingforskipsong)//not showing activity indicator self.isshowloadingforskipsong = no; else if(self.isfirstload || self.isaddpulltorefreshlikesong)//showing indicator [self showhideloading:yes]; pfquery *query = [pfquery querywithclassname:[userplaylistsongs parseclassname]]; [query setlimit:1000]; [query orderbydescending:@"createdat"]; [query wherekey:@"playlist" equalto:self.playlistinfo]; [query includekey:@"playlist"]; [query includekey:@"song"]; [query includekey:@"addedby"]; [query includekey:@"host"]; __weak typeof(self) weakself = self; [self.opearation addoperationwithblock:^{ [query findobjectsinbackgroundwithblock:^(nsarray *objects, nserror *error) { if (objects.count == 0) {//no songs found //if there no records dispatch_async(dispatch_get_main_queue(), ^{ [weakself showhideloading:no]; if(weakself.isfirstload || weakself.isaddpulltorefreshlikesong) {//problem while user pull refresh when there no song [kstoastview ks_showtoast:@"no songs found." duration:1.0f]; } }); } else {//songs found dispatch_async(dispatch_get_main_queue(), ^{ nsmutablearray *arrparsesonglist = [[nsmutablearray alloc] init]; __block nsinteger gettotalobjectscount = 0; for(nsinteger i=0; i<objects.count; i++) { songlistinfo *songlistdata = [[songlistinfo alloc] init]; songlistdata.userplaylistinfo = objects[i]; songlistdata.totlikes = [objects[i][@"likes"] integervalue]; songlistdata.totdislikes = [objects[i][@"dislikes"] integervalue]; songlistdata.isplaying = [objects[i][@"playingstatus"] boolvalue]; songlistdata.songinfo = objects[i][@"song"]; songlistdata.hostinfo = objects[i][@"host"]; songlistdata.addedinfo = objects[i][@"addedby"]; songlistdata.playlistinfo = objects[i][@"playlist"]; songlistdata.alreadyplayedorder = [objects[i][@"alreadyplayedindex"] integervalue]; songlistdata.totrating = songlistdata.totlikes - songlistdata.totdislikes; songlistdata.createddate = songlistdata.userplaylistinfo.createdat; //user specific loading song list. pfquery *querylikedislike = [pfquery querywithclassname:[songlikedislike parseclassname]]; [querylikedislike wherekey:@"songid" equalto:songlistdata.songinfo.objectid]; [querylikedislike wherekey:@"userid" equalto:[singleton getuserid]]; [querylikedislike wherekey:@"playlistid" equalto:songlistdata.playlistinfo.objectid]; [querylikedislike findobjectsinbackgroundwithblock:^(nsarray *objectslike, nserror *error) { gettotalobjectscount += 1; if(error == nil) { if(objectslike.count) { bool isdelete = [objectslike.lastobject[@"deleterecord"] boolvalue]; bool islike = [objectslike.lastobject[@"like"] boolvalue]; if(isdelete) songlistdata.ratingtype = rating_gray; else if(islike) songlistdata.ratingtype = rating_green; else songlistdata.ratingtype = rating_red; } else songlistdata.ratingtype = rating_gray; } else nslog(@"problem while getting rating type"); [arrparsesonglist addobject:songlistdata]; nslog(@"i : %ld, objects : %ld",(long)gettotalobjectscount, (long)objects.count); if(gettotalobjectscount == objects.count) [weakself processaftergettinglikesanddislikeinfo:arrparsesonglist]; }]; } }); } }]; }]; nslog(@"in method -> operation : %ld",(long)self.opearation.operations.count); } else [uialertview showerrorwithmessage:no_internet handler:nil]; } - (void)processaftergettinglikesanddislikeinfo:(nsmutablearray *)arrparsesonglist { nspredicate *filtergrayout = [nspredicate predicatewithformat:@"isplaying == yes"]; nsarray *arrgrayout = [arrparsesonglist filteredarrayusingpredicate:filtergrayout]; nssortdescriptor *asortdescriptorgrayedout = [[nssortdescriptor alloc] initwithkey:@"alreadyplayedorder.intvalue" ascending:yes]; nsarray *arrgrayedoutsong = [nsmutablearray arraywitharray:[arrgrayout sortedarrayusingdescriptors:[nsarray arraywithobject:asortdescriptorgrayedout]]]; nspredicate *filternonplay = [nspredicate predicatewithformat:@"isplaying == no"]; nsarray *arrnonplay = [arrparsesonglist filteredarrayusingpredicate:filternonplay]; nssortdescriptor *asortdescriptorrating = [[nssortdescriptor alloc] initwithkey:@"totrating.intvalue" ascending:no]; nssortdescriptor *asortdescriptorcreateddate = [[nssortdescriptor alloc] initwithkey:@"createddate" ascending:yes]; nsarray *arrsortonnormalsong = [nsmutablearray arraywitharray:[arrnonplay sortedarrayusingdescriptors:[nsarray arraywithobjects:asortdescriptorrating,asortdescriptorcreateddate,nil]]]; if(self.arrsongsdata.count) [self.arrsongsdata removeallobjects]; [self.arrsongsdata addobjectsfromarray:arrgrayedoutsong]; [self.arrsongsdata addobjectsfromarray:arrsortonnormalsong]; [self showhideloading:no]; [self.tblview reloaddata]; }
and call in viewwilldisappear.
- (void)viewwilldisappear:(bool)animated { [super viewwilldisappear:animated]; if(self.queryinstance) [self.queryinstance cancel]; }
thanks help!
so there number of things potentially keeping instance in memory:
- you're adding operations operation queue, , operations retaining contents operations still in queue keep controller instance alive
- your completion blocks using
self
rather creating__weak
reference , using that, while blocks retained controller instance - in completion of first query you're starting query each of the, potentially 1000, results. not flood network requests, each 1 retaining controller instance
- you potentially have 1000 queries running aren't cancelled, depending on when try cancel
mainly, should using weak references in completion blocks when try deallocate controller disappears , completions of queries silently run nothing in background. want cancel or prevent 1000 queries running if user isn't interested though...
Comments
Post a Comment