I have a one-to-many relationship A <--->> B (the to-many part is ordered).
So I have the exact same problem as stated in this question "Core Data Nullify rule doesn't work?": I delete a B that has a relation to an A and immediately after that, I count the number of remaining B's, that A has a relation with and it is the same as before. The accepted answer in that question was to use cascade instead of nullify since what nullify does is:
Nullify sets the pointer to null when the object is deleted. If you have an array of pointers it doesn't remove it, it just sets it to null.
I see 2 issues with that answer:
After experimenting a bit I found out that, if I delete an instance of B it is deleted immediately but the relation to A is not cleared immediately but only after a little delay:
// Method is called by pressing a button
-(void)removeLastBOfA:(A *)instanceOfA
{
// Prints 4
NSLog(@"fetch all b's count before:%d", [context fetchAllBs].count);
// Prints 4
NSLog(@"A's relation to B count before: %d", instanceOfA.relationToB.count);
[context deleteObject:[instanceOfA.relationToB lastObject]];
// Prints 3
NSLog(@"fetch all b's count after:%d", [context fetchAllBs].count);
// Prints 4, but should be 3. Last Object of A's relationToB is still the object that was deleted
NSLog(@"A's relation to B count after: %d", instanceOfA.relationToB.count);
}
Now when pressing the button to call the method above again without doing anything in between, suddenly the relation is updated and "A's relation to B count before: 3" is printed. So the nullify deletion rule does work as I want it to, but with a little delay.
Yes you are right. The answer is not correct. Regarding to second point. The method -deleteOdject does not delete object as you expected it just marks object as deleted. To accomplish deletion you need to save managed object context and then you will see that nullify rule works as expected. If you do not want to save context at this moment you could follow two ways:
Explicitly delete relationship:
NSManagedObject* objectToDelete = [instanceOfA.relationToB lastObject];
[context deleteObject:objectToDelete];
NSMutableSet* relationships = [instanceOfA mutableSetValueForKey:@"relationToB"];
[relationships removeObject:objectToDelete];
Ask context to process its future changes (it means calculate changes caused by your deletion):
[context processPendingChanges];
In your example:
[context deleteObject:[instanceOfA.relationToB lastObject]];
[context processPendingChanges];
// Prints 3
NSLog(@"fetch all b's count after:%d", [context fetchAllBs].count);
NSLog(@"A's relation to B count after: %d", instanceOfA.relationToB.count);
After that you will see expected result.
NSManagedObjectContext does -processPendingChanges
by itself at the end of run loop or when performing -save:
, so that is why you see some delay.
Hope it helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With