Deleting master data after X days

So I have a bunch of objects in Core Data and want them to be deleted automatically after X days (that would be NSDate based). I have done several searches and it seems that you can only delete one main data object at a time, not a group of them, let alone those based on a specific date. I think it is possible for the loop to loop through each object, but it looks like it will be a very heavy processor. Any ideas on where I should be looking for this? Thank.

+3


source to share


3 answers


A loop deleting objects one by one is the correct approach.

Deleting objects in Core Data is extremely difficult. If this is a problem, then Core Data is not suitable for your project and you must be using something else. I recommend FCModel as a very lightweight alternative.

If you are going to use Core Data, it is recommended that you do large operations in the background of the NSOperationQueue, so the main application does not block when objects are deleted. You have to be very careful with master data across multiple threads, the approach is to have a separate managed object context for each thread, just like using the same persistent store coordinator. Never stream a managed object, but you can share an object identifier to get a second copy of the same database record in a different managed object context.



Basically your background thread creates a new context, deletes all objects in the loop, then (on the main thread, preferably see the documentation) preserves the background thread's context. This will merge your changes unless there is a conflict (both contexts are modifying the same object) - in this scenario you have multiple options, I would just stop the whole delete operation and start over.

Apple has good documentation for all issues and sample code available here: https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CoreData/Articles/cdConcurrency.html

It's a little tricky, you have some serious homework to do, but the actual code is very simple if you have your head around how things work. Or just use FCModel which is for fast batch operations.

+2


source


It's not as heavy as you think as a processor :) (of course it depends on the amount of data)

Don't use a loop



- (void)deleteAllObjects
{
NSArray *allEntities = self.managedObjectModel.entities;
for (NSEntityDescription *entityDescription in allEntities)
{
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    [fetchRequest setEntity:entityDescription];

    fetchRequest.includesPropertyValues = NO;
    fetchRequest.includesSubentities = NO;

    NSError *error;
    NSArray *items = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];

    for (NSManagedObject *managedObject in items) {
        [self.managedObjectContext deleteObject:managedObject];
    }

    if (![self.managedObjectContext save:&error]) {
        NSLog(@"Error occurred");
    }
}  
}

      

0


source


As others have noted, iterating over objects is the only way to actually delete objects in Core Data. This is one of those cases where the Core Data approach comes close because it just isn't optimized for that use.

But there are ways to handle this to avoid unwanted delays in your application so that the user doesn't have to wait for your code to intercept a ton of delete requests.

If you have a lot of objects to delete and you don't want to wait for the process to complete, you can fake the initial deletion first and then do the actual deletion when convenient. Something like:

  • Add a custom boolean attribute to an entity type named as toBeDeleted

    with a default value NO

    .
  • Once you have a bunch of objects to delete, set toBeDeleted

    in YES

    for all of them in one step using NSBatchUpdateRequest

    (new in iOS 8). This class is mostly undocumented, so take a look at the header file or BNR blog post about it . You supply the property name and the new attribute value, and Core Data will be a massive, fast update.
  • Make sure your fetch requests check that toBeDeleted

    NO

    . Objects marked for deletion will now be excluded from checkout, even if they still exist.
  • At some point - later, but soon - run some code in the background that retrieves and removes objects with toBeDeleted

    set to YES

    .
0


source







All Articles