ios - Managed object context not merging changes from background context -


i have dual managed object context setup have parent/child moc relationship. parent responsible writing directly database on private queue (nsprivatequeueconcurrencytype) , have child context responsible pulling , saving data main thread (nsmainqueueconcurrencytype).

the contexts work should in when make changes main queue context , save it, changes merged background queue context , written database on background thread.

the issue having when write data directly background queue context , try merge main queue context. objects stored correctly in store, , when merge changes seems work. however, if attempt make nsfetchrequest against main queue context directly after saving data store, data stale , not correct updated data.

below code excerpts should give idea of doing. things note logic returns nsmanagedobjects json work correctly. also, have tested , mergechangesfromcontextdidsavenotification runs before ui attempts make fetch requests against main queue moc. have ideas going on?

// context setup - (nsmanagedobjectcontext *)backgroundwritermanagedobjectcontext {     if (_backgroundwritermanagedobjectcontext != nil)         return _backgroundwritermanagedobjectcontext;      nspersistentstorecoordinator *coordinator = [self persistentstorecoordinator];     if (coordinator != nil)     {         _backgroundwritermanagedobjectcontext = [[nsmanagedobjectcontext alloc] initwithconcurrencytype:nsprivatequeueconcurrencytype];         _backgroundwritermanagedobjectcontext.persistentstorecoordinator = coordinator;         _backgroundwritermanagedobjectcontext.mergepolicy = nsmergebypropertystoretrumpmergepolicy;         _backgroundwritermanagedobjectcontext.undomanager = nil;     }     return _backgroundwritermanagedobjectcontext; }  - (nsmanagedobjectcontext *)managedobjectcontext {     if (_managedobjectcontext != nil)         return _managedobjectcontext;      nspersistentstorecoordinator *coordinator = [self persistentstorecoordinator];     if (coordinator != nil)     {         _managedobjectcontext = [[nsmanagedobjectcontext alloc] initwithconcurrencytype:nsmainqueueconcurrencytype];         _managedobjectcontext.parentcontext = _backgroundwritermanagedobjectcontext;         _managedobjectcontext.mergepolicy = nsmergebypropertystoretrumpmergepolicy;         _managedobjectcontext.stalenessinterval = 0.0;     }     return _managedobjectcontext; }  // save moc - (void)savemanagedobjectcontext {     @try     {         // perform synchronous process save main moc         [_managedobjectcontext performblockandwait:^(void)         {             __block nserror *error = nil;              // push changes in main context background writer context             if (![_managedobjectcontext trylock])                 [vs_log vs_logerror:[nsstring stringwithformat:@"vs_coredatamanger - unable lock managed object context: %@", error.localizeddescription]];              if (![_managedobjectcontext save:&error])                 [vs_log vs_logerror:[nsstring stringwithformat:@"vs_coredatamanger - error saving managed object context: %@", error.localizeddescription]];              [_managedobjectcontext unlock];              // save background writer context             [_backgroundwritermanagedobjectcontext performblock:^(void)             {                 error = nil;                  if (![_backgroundwritermanagedobjectcontext trylock])                     [vs_log vs_logerror:[nsstring stringwithformat:@"vs_coredatamanger - unable lock background writer managed object context: %@", error.localizeddescription]];                  if (![_backgroundwritermanagedobjectcontext save:&error])                     [vs_log vs_logerror:[nsstring stringwithformat:@"vs_coredatamanger - error saving background writer managed object context: %@", error.localizeddescription]];                  [_backgroundwritermanagedobjectcontext unlock];             }];         }];     }     @catch (nsexception *exception)     {         [vs_log vs_logexception:exception];     } }  // code runs when attempting save objects web service call [_backgroundwritermanagedobjectcontext performblock:^(void)     {         // create new process object , add dictionary         __block vs_coredatarequest *request = [[vs_coredatarequest alloc] init];          // .. logic here deserializes json , returns array of nsmanagedobjects           // perform synchronous process save main moc          @try          {              nserror *error = nil;               [[nsnotificationcenter defaultcenter] addobserver:self selector:@selector(mergechangesfromcontextdidsavenotification:) name:nsmanagedobjectcontextdidsavenotification object:_backgroundwritermanagedobjectcontext];               if (![_backgroundwritermanagedobjectcontext trylock])                  [vs_log vs_logerror:[nsstring stringwithformat:@"vs_coredatamanger - unable lock background writer managed object context: %@", error.localizeddescription]];               if (![_backgroundwritermanagedobjectcontext save:&error])                  [vs_log vs_logerror:[nsstring stringwithformat:@"vs_coredatamanger - error saving background writer managed object context: %@", error.localizeddescription]];               [_backgroundwritermanagedobjectcontext unlock];               // submit changes forground context              [_managedobjectcontext performblock:^(void)              {                  nsmutablearray *objects = [[nsmutablearray alloc] init];                   // iterate through updated objects , find them in main thread moc                  (vs_basemanagedobject *object in request.objects)                  {                      // object main managed object context                      nserror *error;                      nsmanagedobject *obj = [_managedobjectcontext existingobjectwithid:object.objectid error:&error];                       if (error)                          [vs_log vs_logerror:[nsstring stringwithformat:@"vs_coredatamanager - error: %@", error.localizeddescription]];                       if (obj)                      {                          [_managedobjectcontext refreshobject:obj mergechanges:yes];                          [objects addobject:obj];                      }                  }                   // return method ui can regain control              }];          }          @catch (nsexception *exception)          {             [vs_log vs_logexception:exception];             return;          }      }];  // merges changes parent child context - (void)mergechangesfromcontextdidsavenotification:(nsnotification *)notification {     // remove observer     [[nsnotificationcenter defaultcenter] removeobserver:self name:nsmanagedobjectcontextdidsavenotification object:_backgroundwritermanagedobjectcontext];      // merge changes     [_managedobjectcontext mergechangesfromcontextdidsavenotification:notification]; } 

you're not calling process pending changes.


Comments

Popular posts from this blog

c# - Operator '==' incompatible with operand types 'Guid' and 'Guid' using DynamicExpression.ParseLambda<T, bool> -