Links of interest:
http://stackoverflow.com/questions/4874193/core-data-willsave-method
http://www.cocoabuilder.com/archive/cocoa/134497-coredata-using-willsave-to-update-timestamps-causes-hang.html
https://cocoacasts.com/three-features-of-nsmanagedobject-you-may-not-know-about/


– (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSError *error = nil;
// Load the data model
NSManagedObjectModel *model = [NSManagedObjectModel mergedModelFromBundles:nil];
// Set up the SQLite store
NSURL *documentsDirectory = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
NSURL *storeURL = [documentsDirectory URLByAppendingPathComponent:@"Example.sqlite"];
NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];
if (![coordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
NSAssert(NO, @"Unable to add persistent store: %@", error);
}
// Create a foreground managed object context
NSManagedObjectContext *foreground = [[NSManagedObjectContext alloc] init];
[foreground setPersistentStoreCoordinator:coordinator];
[foreground.userInfo setValue:@"Foreground" forKey:@"name"];
// Create a background managed object context — we'll generate
// an optimistic locking conflict in this one
NSManagedObjectContext *background = [[NSManagedObjectContext alloc] init];
[background setPersistentStoreCoordinator:coordinator];
[background.userInfo setValue:@"Background" forKey:@"name"];
// Create an entity instance and save it into our store
NSEntityDescription *entity = [[model entitiesByName] valueForKey:@"Event"];
NSManagedObject *event = [[NSManagedObject alloc] initWithEntity:entity insertIntoManagedObjectContext:foreground];
[event setValue:[NSDate date] forKey:@"timeStamp"];
if (![foreground save:&error]) {
NSAssert(NO, @"Unable to save foreground context: %@", error);
}
// Now load this same entity into the background context
NSManagedObjectID *objectID = event.objectID;
NSManagedObject *backgroundEntity = [background objectWithID:objectID];
[background deleteObject:backgroundEntity];
// Change it in the foreground context and save to the store
[event setValue:[NSDate dateWithTimeIntervalSince1970:15] forKey:@"timeStamp"];
if (![foreground save:&error]) {
NSAssert(NO, @"Unable to save foreground context: %@", error);
}
// Trigger optimistic locking exception in the background context
NSLog(@"Triggering a conflicted save…");
if (![background save:&error]) {
NSLog(@"Unable to save background context: %@", error);
}
[self.window makeKeyAndVisible];
return YES;
}

view raw

AppDelegate.m

hosted with ❤ by GitHub


#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
@interface Event : NSManagedObject
@property (nonatomic, retain) NSDate * timeStamp;
@end

view raw

Event.h

hosted with ❤ by GitHub


#import "Event.h"
@implementation Event
@dynamic timeStamp;
– (void)willSave {
[super willSave];
NSLog(@"%@ (in %@) received willSave", [[self.managedObjectContext userInfo] valueForKey:@"name"], self.objectID);
if ([self isDeleted]) {
NSLog(@"Would delete any associated image now.");
}
}
– (void)didSave {
[super didSave];
NSLog(@"%@ (in %@) received didSave", [[self.managedObjectContext userInfo] valueForKey:@"name"], self.objectID);
}
@end

view raw

Event.m

hosted with ❤ by GitHub


<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model name="" userDefinedModelVersionIdentifier="" type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="878" systemVersion="11C74" minimumToolsVersion="Automatic" macOSVersion="Automatic" iOSVersion="Automatic">
<entity name="Event" representedClassName="Event">
<attribute name="timeStamp" optional="YES" attributeType="Date"/>
</entity>
<elements>
<element name="Event" positionX="261" positionY="189" width="128" height="60"/>
</elements>
</model>


// Create an entity instance and save it into our store
2012-01-10 13:10:26.123 CoreDataMessages[65209:fb03] Foreground (in 0x6d61da0 <x-coredata:///Event/tFC120BB0-B9E6-4BE5-A0D1-B8268377C9CA2>) received willSave
2012-01-10 13:10:26.138 CoreDataMessages[65209:fb03] Foreground (in 0x6d64880 <x-coredata://F31D363D-5E34-4595-A852-E029B0B01B62/Event/p1>) received didSave
// Change it in the foreground context and save to the store
2012-01-10 13:10:26.139 CoreDataMessages[65209:fb03] Foreground (in 0x6d64880 <x-coredata://F31D363D-5E34-4595-A852-E029B0B01B62/Event/p1>) received willSave
2012-01-10 13:10:26.142 CoreDataMessages[65209:fb03] Foreground (in 0x6d64880 <x-coredata://F31D363D-5E34-4595-A852-E029B0B01B62/Event/p1>) received didSave
// Trigger optimistic locking exception in the background context
2012-01-10 13:10:26.143 CoreDataMessages[65209:fb03] Triggering a conflicted save…
2012-01-10 13:10:26.144 CoreDataMessages[65209:fb03] Background (in 0x6d64880 <x-coredata://F31D363D-5E34-4595-A852-E029B0B01B62/Event/p1>) received willSave
2012-01-10 13:10:26.145 CoreDataMessages[65433:fb03] Would delete any associated image now.
2012-01-10 13:10:26.148 CoreDataMessages[65209:fb03] Unable to save background context: Error Domain=NSCocoaErrorDomain Code=133020 "The operation couldn’t be completed. (Cocoa error 133020.)" UserInfo=0x6d623c0 {conflictList=(
"NSMergeConflict (0x6d65800) for NSManagedObject (0x6d64940) with objectID '0x6d64880 <x-coredata://F31D363D-5E34-4595-A852-E029B0B01B62/Event/p1>' with oldVersion = 1 and newVersion = 2 and old object snapshot = {\n timeStamp = \"2012-01-10 18:10:26 +0000\";\n} and new cached row = {\n timeStamp = \"1970-01-01 00:00:15 +0000\";\n}"
)}

view raw

Output

hosted with ❤ by GitHub

https://developer.apple.com/reference/coredata/nsmanagedobject/1506209-willsave
https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CoreData/ObjectValidation.html