简体   繁体   中英

Magical Records: Loading a record to be updated in a local context

I am currently saving a record using Magical Records as follows:

NSManagedObjectID *objID = [existingItem objectID];
[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext){
    CustomNSMO *item;
    if(newItem) item = [CustomNSMO MR_createEntityInContext:localContext];
    else item = [localContext objectWithID:objID]; 
    item.sync = 1;
    item.relID = @"Some String";
 }completion:^(BOOL success, NSError *error) {
   //do something
 }];

This works fine. If I query all items where sync has been set I get back the results I expect ie

  NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(sync >= 1)"];
  NSArray *objects = [CustomNSMO MR_findAllSortedBy:@"sync" ascending:YES withPredicate:predicate];

gives me an array of my new or updated objects.

I then (after some server business) want to find all results with sync >= 1 and set it to zero. This is when the strange behaviour occurs. I have been trying to get an array of results within a local context via either

  NSManagedObjectContext *localContext    = [NSManagedObjectContext MR_context];
  NSArray *objects = [CustomNSMO MR_findAllSortedBy:@"sync" ascending:YES withPredicate:predicate inContext:localContext];
  for(CustomNSMO *item in objects) {
     item.sync = 0;
  }
  [localContext MR_saveToPersistentStoreAndWait];

or

  [MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext){
    NSArray *objects = [CustomNSMO MR_findAllSortedBy:@"sync" ascending:YES withPredicate:predicate inContext:localContext];
    for (SyncObject *currentObj in objects)
    {
        currentObj.sync = @0;
    }
  } completion:nil];

If relID is set when the item is first created then this is all fine. I can edit the item (changing the relID ) and the changes is observed in all contexts. However, if the first time the item is created it has a relID of nil then problems occur after using the code above to do the following:

1) Update the item changing a nil relID to some non- nil value

2) Save the item to the database

3) Load the item (by searching on ' sync ')

In any context apart from MR_defaultContext relID stays as nil . If I look at the object in MR_defaultContext then I see the correct updated relID . If I look at it in a different context it is nil . This means that the update of sync on a local context overrides the value of relID on the default context (setting it to nil ).

Some thoughts:

if(newItem) item = [CustomNSMO MR_createEntityInContext:context];

should be:

if(newItem) item = [CustomNSMO MR_createEntityInContext:localContext];

You don't want to use a different context inside +saveWithBlock: .

Also, this line:

else item = [localContext objectID];

I think you mean [localContext objectWithID:objID] or [localContext existingObjectWithID:objID error:error] ?

Turns out it is a bug with the database store we are using below Core Data.

https://github.com/project-imas/encrypted-core-data/issues/118

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM