Delete an object in core data

15,413

Solution 1

What Mike Weller wrote is right. I'll expand the answer a little bit.

First you need to create a NSFetchRequest like the following:

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];    
[fetchRequest setEntity:[NSEntityDescription entityForName:@"Selection" inManagedObjectContext:context]];

Then you have to set the predicate for that request like the following:

[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"content == %@ AND page_id == %@ AND book_id == %@", contentVal, pageVal, bookVal]];

where

NSString* contentVal = @"test";
NSNumber* pageVal = [NSNumber numberWithInt:5];
NSString* bookVal = @"1331313";

I'm using %@ since I'm supposing you are using objects and not scalar values.

Now you perform a fetch in the context with the previous request:

NSError* error = nil;
NSArray* results = [context executeFetchRequest:fetchRequest error:&error];

results contains all the managed objects that match that predicate.

Finally you could grab the objects and call a deletion on them.

[context deleteObject:currentObj];

Once done you need to save the context as per the documentation.

Just as a new object is not saved to the store until the context is saved, a deleted object is not removed from the store until the context is saved.

Hence

NSError* error = nil;
[context save:&error];

Note that save method returns a bool value. So you can use an approach like the following or display an alert to the user. Source NSManagedObjectContext save error.

NSError *error = nil;
if ([context save:&error] == NO) {
    NSAssert(NO, @"Save should not fail\n%@", [error localizedDescription]);
    abort();
}

Solution 2

You should perform a fetch request using an NSPredicate with the appropriate conditions, and then call the deleteObject: method on NSManagedObjectContext with each object in the result set.

Solution 3

In addition to Mike Weller and flexaddicted, after calling [context deleteObject:currentObj]; you need to save: context:

NSError *error = nil;
[context save:&error];

As from documentation:

Just as a new object is not saved to the store until the context is saved, a deleted object is not removed from the store until the context is saved.

That made matter in my case.

Share:
15,413
samir
Author by

samir

iOS developer

Updated on June 18, 2022

Comments

  • samir
    samir almost 2 years

    I have an entity in my core data model like this:

    @interface Selection : NSManagedObject
    
    @property (nonatomic, retain) NSString * book_id;
    @property (nonatomic, retain) NSString * contenu;
    @property (nonatomic, retain) NSNumber * page_id;
    @property (nonatomic, retain) NSNumber * nbrOfOccurences;
    @property (nonatomic, retain) NSString * next;
    @property (nonatomic, retain) NSString * previous;
    

    I have created many Selections and saved them in Core Data and now I would like to delete some selections with some criteria. For example, I would like to delete a Selection object if matches the following:

    content = test
    page_id = 5
    book_id = 1331313
    

    How I can do this?

  • Evan R
    Evan R about 10 years
    This is definitely necessary—I suggested it as an edit to the accepted answer.
  • Evan R
    Evan R about 10 years
    @flexaddicted This should be edited to include the [context save:&error] call that needs to take place, or else the deleted object doesn't get removed from the store. In addition, if you're using a persistent store, it has to get saved like so: [context saveToPersistentStore:&error].
  • Lorenzo B
    Lorenzo B about 10 years
    @EvanR Modified my answer taking into account your comment.
  • Benjohn
    Benjohn almost 9 years
    It's worth adding fetchRequest.includesPropertyValues = NO; in the setup so that the objects arrive more cheaply as faults.