Nil check failing raw data retrieval / unexpected results?

I have a Core Data layer with several thousand objects that is constantly in sync with the server. The synchronization process uses sample queries to check for delete_at for soft deletion. There is one context that performs save operations in an executeBlockAndWait call. Relationship mapping is handled by the RestKit library.

The CoreDataEntity class is a subclass of NSManagedObject, and it is also a superclass for all of our various classes of master data objects. It has some attributes that are inherited by all our objects, such as deleted_at, entity_id, and all methods of selecting and synchronizing templates.

My problem is that some select queries seem to return inconsistent results after making changes to the objects. For example, after deleting an object (setting deleted_at to the current date):

[CoreDataEntity fetchEntitiesWithPredicate:[NSPredicate predicateWithFormat:@"deleted_at==nil"]]; 

Returns results using deleted_at == [NSDate today]

I successfully worked on this behavior, additionally sorting through the results and deleting entities using set_set, however, I cannot fix the opposite problem:

 [CoreDataEntity fetchEntitiesWithPredicate:[NSPredicate predicateWithFormat:@"deleted_at!=nil"]]; 

It returns an empty array under the same conditions, which prevents subsequent server synchronization.

I confirmed that the object is set to delete_at, and saving the context was successful. I just don’t understand where to reset which cache causes stale results?

Thanks for any help!

Edit: By adding a little more information, it seems that as soon as one of these objects is damaged, the only way to get it to register is to change the value again. Could this be some kind of Core Data index not updating when the value changes?

Update: seems to be a problem with RestKit https://github.com/RestKit/RestKit/issues/2218

+5
source share
3 answers

First of all, after saving, did you look at the store to make sure that there are any changes? Without looking through your entire Core Data stack, it's hard to see what might be wrong. If you save and see changes in the store, the question arises in your contexts. How are they built and when. If you are dealing with sister contexts that can cause problems.

More information on what your main data stack looks like.

Yes, there are changes. As I mentioned in the question, I can skip my results and delete all successfully deleted files

This is not my question. There is a difference between viewing objects in memory and viewing them in an SQLite file on disk. The questions I ask about this are:

  • Whether changes are saved to disk before re-querying them.
  • You work with multiple contexts and are potentially trying to extract from an outdated brother.

So my questions are about changes on disk and what your main data stack looks like.

Threading

If you use one context, are you using more than one thread in your application? If so, are you using this context in more than one thread?

I see a situation where, if you break the rules for restricting the flow, you can corrupt data like this.

0
source

Apparently you are using the syntax sugar extension for Core Data. I suppose in your case it is SheepData, right?

fetchEntitiesWithPredicate: implemented as follows:

 + (NSArray*)fetchEntitiesWithPredicate:(NSPredicate*)aPredicate { return [self fetchEntitiesWithPredicate:aPredicate inContext:[SheepDataManager sharedInstance].managedObjectContext]; } 

Are you sure that [SheepDataManager sharedInstance].managedObjectContext gets all the changes you make to your objects? Does it receive persistence notifications or is it a child context of the save context?

Try replacing your single line selection with the following:

 [<your saving context> performBlockAndWait:^{ NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"CoreDataEntity"]; request.predicate = [NSPredicate predicateWithFormat:@"deleted_at==nil"]; NSArray *results = [<your saving context> executeFetchRequest:request error:NULL]; }]; 
0
source

Try adding the optional attribute deleted , which is a bool with a default value of false . Then the attribute is always set, and you can search for objects that are either true or false , depending on your needs at the moment. If true , you can look at deleted_at to find out when.

Alternatively, try setting the deleted_at attribute to some old date (for example, perhaps January 1, 1980), then everything that is not deleted will have a fixed date that is too old to be set by the user.

Edit: There is probably some problem with deleted_at that has never been touched by some objects that confuse the system. It is also possible that you have made a selection request to return results in a dictionary style, in which case the latest changes will not be reflected in the selection results.

-1
source

All Articles