Search code examples
objective-ccore-datansmanagedobject

Core-Data willSave: method


I have an attribute modificationDate in my Entity A. I want to set its value whenever NSManagedObject is saved. However, if i try to do that in NSManagedObject willSave: method, i get an error:

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Failed to process pending changes before save.  The context is still dirty after 100 attempts.  Typically this recursive dirtying is caused by a bad validation method, -willSave, or notification handler.' ***

So, i'm wondering, what's the best way to set the value of modificationDate?


Solution

  • From the NSManagedObject docs for willSave:

    If you want to update a persistent property value, you should typically test for equality of any new value with the existing value before making a change. If you change property values using standard accessor methods, Core Data will observe the resultant change notification and so invoke willSave again before saving the object’s managed object context. If you continue to modify a value in willSave, willSave will continue to be called until your program crashes.

    For example, if you set a last-modified timestamp, you should check whether either you previously set it in the same save operation, or that the existing timestamp is not less than a small delta from the current time. Typically it’s better to calculate the timestamp once for all the objects being saved (for example, in response to an NSManagedObjectContextWillSaveNotification).

    So maybe something along the lines of:

    -(void)willSave {
        NSDate *now = [NSDate date];
        if (self.modificationDate == nil || [now timeIntervalSinceDate:self.modificationDate] > 1.0) {
            self.modificationDate = now;
        }
    }
    

    Where you can adjust the 1.0 to reflect the minimum delta between your expected save requests.