Using Core Data in IOS6 (delete/edit) -
i saving latest internet request of tableviewdata in (core data) entity, have problems error exceptions "faults". have 2 methods 'loaddata' gets latest 'ordersitems' loaded in tableview , 'loadthumbnails' try cache thumbnail core data entity. problem occurs when managedobject gets deleted , thumbnail method still tries access it. though made variable stopthumbnails stop loadthumbnails method, problem keeps occurring.
what proper ios 6 way lazyload images , save them coredata check if object has not been deleted? found core data multi thread application useful newbie understanding of core data still limited , have problems writing code. read apple docs http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/coredata/articles/cdconcurrency.html hard understand completely.
i want @ least http request load asychronous (but preferably as possible) came following:
-(void)viewdidload { nsfetchrequest *fetchreq = [nsfetchrequest fetchrequestwithentityname:@"orderitems"]; fetchreq.sortdescriptors = [nsarray arraywithobject:[nssortdescriptor sortdescriptorwithkey:@"name" ascending:yes]]; self.data = [self.managedobjectcontext executefetchrequest:fetchreq error:nil]; myfilter = @"filter=companyx"; [self loaddata]; } -(void)loaddata { dispatch_async( dispatch_get_global_queue(dispatch_queue_priority_default, 0), ^{ //json request url nsdictionary *reqdata = myorderjsonrequest(myfilter); dispatch_async( dispatch_get_main_queue(), ^{ if(reqdata!=null && reqdata!=nil) { //request successful delete items entity before inserting new ones stopthumbnails = yes; for(int i=self.data.count-1;i>=0;i--) { [self.managedobjectcontext deleteobject:[self.data objectatindex:i]]; } [self.managedobjectcontext save:nil]; if(reqdata.count>0) { //insert latest updates (nsdictionary *row in reqdata){ orderitem *item = [nsentitydescription insertnewobjectforentityforname:@"orderitem" inmanagedobjectcontext:self.managedobjectcontext]; item.order_id = [nsnumber numberwithint:[[row objectforkey:@"order_id"] intvalue]]; item.description = [row objectforkey:@"description"]; item.thumbnail_url = [row objectforkey:@"thumbnail_url"]; } [self.managedobjectcontext save:nil]; } nsfetchrequest *fetchreq = [nsfetchrequest fetchrequestwithentityname:@"orderitems"]; fetchreq.sortdescriptors = [nsarray arraywithobject:[nssortdescriptor sortdescriptorwithkey:@"name" ascending:yes]]; self.data = [self.managedobjectcontext executefetchrequest:fetchreq error:nil]; [tableview reloaddata]; //load thumbnails asynchronous stopthumbnails = no; [self loadthumbnails]; } else{ //no internet } }); }); } -(void)loadthumbnails { if(!loadingthumbnails) { loadingthumbnails = yes; dispatch_async( dispatch_get_global_queue(dispatch_queue_priority_default, 0), ^{ (int i=0;i<self.data.count; i++) { if(!stopthumbnails) { orderitem *item = [self.data objectatindex:i]; if(item.thumbnail==null) { //asynchronous image request nsurl *image_url = [nsurl urlwithstring:item.thumbnail_url]; nsdata *image_data = [nsdata datawithcontentsofurl:image_url]; dispatch_async( dispatch_get_main_queue(), ^{ if(image_data!=nil && image_data!=null && !stopthumbnails) { //image request successful item.thumbnail = image_data; [self.managedobjectcontext save:nil]; //reload affected tableviewcell nsindexpath* rowtoreload = [nsindexpath indexpathforrow:i insection:0]; nsarray* rowstoreload = [nsarray arraywithobjects:rowtoreload, nil]; [tableview reloadrowsatindexpaths:rowstoreload withrowanimation:uitableviewrowanimationfade]; } else { loadingthumbnails = no; return; } }); } if(stopthumbnails) { dispatch_async( dispatch_get_main_queue(), ^{ loadingthumbnails = no; return; }); } } else{ dispatch_async( dispatch_get_main_queue(), ^{ loadingthumbnails = no; return; }); } } dispatch_async( dispatch_get_main_queue(), ^{ loadingthumbnails = no; return; }); }); } } any of course appreciated :)
well dont know if right approach works, i'll mark answer.
to on background used second nsmanagedobjectcontext (moc) , merge changes main moc. dispatch queue works great although had use nsmanagedobjectcontextdidsavenotification in order merge changes of 2 contexts.
since ios 5 possible use blocks instead merging you. decided use instead of dispatch way (this way didnt have use notofications).
also using blocks got same problem (faults) when object got selected on background queue while deleted on different queue. decided instead of deleting right away, insert nsdate 'deleted' property orderitem. have timer delete check see if there objects have been deleted longer 10 minutes ago. way sure no thumbnail still downloading. works. though still know id right approach :)
Comments
Post a Comment