ios - NSFetchRequest Hangs -


i'm having trouble app hanging on nsfetchrequest. i've been reading quite few hours. there apparently threading issue going on, can't figure out how fix it.

i'm downloading json object server, parsing , storing in coredata model. occurs on background thread complete before app hangs. here code occurs:

- (void) populateregistrationlist:(nsstring *) list script:(nsstring *)script {      nsurl *url = [nsurl urlwithstring:[primary_url stringbyappendingstring:script]];     nsurlrequest *request = [nsurlrequest requestwithurl:url];     nsurlsessionconfiguration *configuration = [nsurlsessionconfiguration ephemeralsessionconfiguration];     nsurlsession *session = [nsurlsession sessionwithconfiguration:configuration];     nsurlsessiondownloadtask *task = [session downloadtaskwithrequest:request         completionhandler:^(nsurl *localfile, nsurlresponse *response, nserror *error) {             if (!error) {                  nsarray *jobj = [nsjsonserialization jsonobjectwithdata:[nsdata datawithcontentsofurl:localfile]                                                                 options:kniloptions                                                                   error:nil];                 // make sure result successful                 if (![[jobj valueforkey:@"result"] isequaltostring:@"success"]) {                     return;                 }                  // context pointer database model                 appdelegate* appdelegate = [uiapplication sharedapplication].delegate;                 self.managedobjectcontext = appdelegate.managedobjectcontext;                  // clear out data previous downloads                 [self dumptable:list];                  nsarray *jarr = (nsarray *) [jobj valueforkey:@"message"];                  (int i=0; i<[jarr count]; i++) {                     nsdictionary *dict = [jarr objectatindex:i];                     [self committocoredata:dict];                      nserror *error;                     if (![self.managedobjectcontext save:&error])                         nslog(@"whoops, couldn't save: %@", [error localizeddescription]);                 }                  // set user default yes tell registrationtwoviewcontroller done                 [[nsuserdefaults standarduserdefaults] setbool:yes forkey:registration_lists_retrieved];                 [[nsuserdefaults standarduserdefaults] synchronize];              }         }];    [task resume]; } 

subsequently, in main thread, execute fetch request access data this:

@implementation choosesupergroupviewcontroller  - (void)viewdidload {     [super viewdidload];      // context pointer database model     appdelegate* appdelegate = [uiapplication sharedapplication].delegate;     self.managedobjectcontext = appdelegate.managedobjectcontext;      nslog(@"about fetched objects");         [self.managedobjectcontext performblockandwait:^{         nsfetchrequest *fetchrequest = [[nsfetchrequest alloc] initwithentityname:@"supergroups"];         nserror *error;         self.fetchedobjects = [self.managedobjectcontext executefetchrequest:fetchrequest error:&error];         nslog(@"done fetch request");     }]; }         

unfortunately, hangs on self.fetchedobjects line. realize using 2 different threads, know background thread has completed before attempt fetch request. why have concern myself thread @ point? don't see how race condition can occur.

what do fix this? can force fetch request run on same background thread somehow? of posts , articles have read on seem way complicated or don't address threading issue @ all. i'm stuck , don't know else do.

any appreciated. thanks.

this appdelegate:

- (nsmanagedobjectcontext *) managedobjectcontext {     if (_managedobjectcontext != nil) {         return _managedobjectcontext;     }     nspersistentstorecoordinator *coordinator = [self persistentstorecoordinator];     if (coordinator != nil) {         _managedobjectcontext = [[nsmanagedobjectcontext alloc] initwithconcurrencytype:nsprivatequeueconcurrencytype];         [_managedobjectcontext setpersistentstorecoordinator: coordinator];     }      return _managedobjectcontext; }  - (nsmanagedobjectmodel *)managedobjectmodel {     if (_managedobjectmodel != nil) {         return _managedobjectmodel;     }     _managedobjectmodel = [nsmanagedobjectmodel mergedmodelfrombundles:nil];      return _managedobjectmodel; }  - (nspersistentstorecoordinator *)persistentstorecoordinator {     if (_persistentstorecoordinator != nil) {         return _persistentstorecoordinator;     }     nsurl *storeurl = [nsurl fileurlwithpath: [[self applicationdocumentsdirectory]                                                stringbyappendingpathcomponent: @"phonebook.sqlite"]];     nserror *error = nil;     _persistentstorecoordinator = [[nspersistentstorecoordinator alloc]                                    initwithmanagedobjectmodel:[self managedobjectmodel]];     if(![_persistentstorecoordinator addpersistentstorewithtype:nssqlitestoretype                                                   configuration:nil url:storeurl options:nil error:&error]) {         /*error store creation should handled in here*/     }      return _persistentstorecoordinator; } 

it doesn't matter background thread has completed, problem can't safely use same managed object context on multiple threads without ensuring synchronization-- possibly using gcd calls dispatch_async preferably using core data's built-in synchronization system. don't know why it's failing in case, you're violating major rule of safe core data usage, bad results expected.

to use core data's built-in syncing, create context using nsmainqueueconcurrencytype or nsprivatequeueconcurrencytype. then, whenever use context (or objects have fetched context), put code inside performblock or performblockandwait call. guarantee synchronous access regardless of number of threads or queues.

alternately, create new managed object context background thread. there's no reason not have more one. work on separate context, , listen nsmanagedobjectcontextdidsavenotification on main thread merge in new changes.

but whatever do, don't use same context on multiple threads without adequate precautions. when works, it's chance. it'll fail eventually.


Comments

Popular posts from this blog

python - Subclassed QStyledItemDelegate ignores Stylesheet -

java - HttpClient 3.1 Connection pooling vs HttpClient 4.3.2 -

SQL: Divide the sum of values in one table with the count of rows in another -