Reputation: 221
Sometimes i have this error with coredata in the same place. Sometimes its ok, and in other time i have this error. What does it mean? I can't find anything about it :(
ps sorry for my english :)
conflictList = ( "NSMergeConflict (0xd447640) for NSManagedObject (0xd41b370) with objectID '0xd41b500 ' with oldVersion = 4 and newVersion = 5 and old object snapshot = {\n album = \"{(\n)}\";\n audios = \"{(\n)}\";\n bdate = \"\";\n city = \"\";\n country = \"\";\n dialog = \"{(\n)}\";\n domain = \"white.smoke\";\n faculty = 0;\n facultyName = \"\";\n firstName = White;\n graduation = 0;\n homePhone = \"\";\n isFriend = 1;\n isMe = 0;\n lastName = Smoke;\n mobilePhone = \"\";\n nickName = \"\";\n online = 1;\n photo = \"\";\n photoBig = \"\";\n photoComments = \"{(\n)}\";\n photoMedium = \"\";\n photoRec = \"http://cs10609.vkontakte.ru/u79185807/e_8c949409.jpg\";\n photos = \"{(\n (entity: Photo; id: 0xd482c50 ; data: {\n aid = 121594781;\n album = nil;\n comments = \\"\\";\n commentsCount = 0;\n created = \\"2010-12-10 03:45:01 GMT\\";\n owner = \\"0xd41b500 \\";\n \\"owner_id\\" = 79185807;\n photosNumber = 0;\n pid = 196997145;\n src = \\"http://cs10609.vkontakte.ru/u79185807/121594781/m_\\";\n \\"src_big\\" = \\"http://cs10609.vkontakte.ru/u79185807/121594781/x_\\";\n \\"src_small\\" = \\"http://cs10609.vkontakte.ru/u79185807/121594781/s_\\";\n \\"src_xbig\\" = nil;\n \\"src_xxbig\\" = nil;\n wallRel = \\"0xd480840 \\";\n}),\n (entity: Photo; id: 0xd431570 ; data: {\n aid = 121594781;\n album = nil;\n comments = \\"\\";\n commentsCount = 0;\n created = \\"2010-12-10 03:43:01 GMT\\";\n owner = \\"0xd41b500 \\";\n \\"owner_id\\" = 79185807;\n photosNumber = 0;\n pid = 196997029;\n src = \\"http://cs10609.vkontakte.ru/u79185807/121594781/m_\\";\n \\"src_big\\" = \\"http://cs10609.vkontakte.ru/u79185807/121594781/x_\\";\n \\"src_small\\" = \\"http://cs10609.vkontakte.ru/u79185807/121594781/s_\\";\n \\"src_xbig\\" = nil;\n \\"src_xxbig\\" = nil;\n wallRel = \\"0xd42d500 \\";\n})\n)}\";\n rate = \"-19\";\n sex = 0;\n statuses = \"{(\n)}\";\n timezone = 0;\n uid = 79185807;\n university = 0;\n universityName = \"\";\n videos = \"{(\n)}\";\n wall = \"{(\n)}\";\n wallPostsCount = 0;\n wallReplies = \"{(\n (entity: WallReply; id: 0xd448270 ; data: )\n)}\";\n wallSender = \"{(\n)}\";\n} and new cached row = {\n bdate = \"\";\n city = \"\";\n country = \"\";\n domain = \"white.smoke\";\n faculty = 0;\n facultyName = \"\";\n firstName = White;\n graduation = 0;\n homePhone = \"\";\n isFriend = 1;\n isMe = 0;\n lastName = Smoke;\n mobilePhone = \"\";\n nickName = \"\";\n online = 1;\n photo = \"\";\n photoBig = \"\";\n photoMedium = \"\";\n photoRec = \"http://cs10609.vkontakte.ru/u79185807/e_8c949409.jpg\";\n rate = \"-19\";\n sex = 0;\n timezone = 0;\n uid = 79185807;\n university = 0;\n universityName = \"\";\n wallPostsCount = 0;\n}" );
Upvotes: 22
Views: 15807
Reputation: 3496
Swift 4
private(set) lazy var mainContext: NSManagedObjectContext = {
let context = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
context.parent = privateContext
context.mergePolicy = NSMergePolicy(merge: .overwriteMergePolicyType)
// Or we can use Trumping
// .mergeByPropertyObjectTrumpMergePolicyType
// .mergeByPropertyStoreTrumpMergePolicyType
// Rolling back is another option
// .rollbackMergePolicyType
return context
}()
Upvotes: 5
Reputation: 487
In short - enable Merge Policy add this to your MOC setup:
objective-C
[_managedObjectContext setMergePolicy:[[NSMergePolicy alloc] initWithMergeType:NSMergeByPropertyObjectTrumpMergePolicyType]];
Swift
lazy var managedObjectContext: NSManagedObjectContext? = {
let coordinator = self.persistentStoreCoordinator
if coordinator == nil {
return nil
}
var managedObjectContext = NSManagedObjectContext()
managedObjectContext.persistentStoreCoordinator = coordinator
//add this line
managedObjectContext.mergePolicy = NSMergePolicy(mergeType: NSMergePolicyType.MergeByPropertyObjectTrumpMergePolicyType);
return managedObjectContext
}()
Upvotes: 17
Reputation: 5526
I got the same merge conflict, while saving the context. see apple doc here
I resolved the conflicts by using NSMergePolicy
- (BOOL)resolveConflicts:(NSArray *)list error:(NSError **)error
set policyType to NSOverwriteMergePolicyType
while creating the NSMergePolicy object
NSOverwriteMergePolicyType: Specifies a policy that overwrites state in the persistent store for the changed objects in conflict.
`
if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
NSArray * conflictListArray = (NSArray*)[[error userInfo] objectForKey:@"conflictList"];
NSLog(@"conflict array: %@",conflictListArray);
NSError * conflictFixError = nil;
if ([conflictListArray count] > 0) {
NSMergePolicy *mergePolicy = [[NSMergePolicy alloc] initWithMergeType:NSOverwriteMergePolicyType];
if (![mergePolicy resolveConflicts:conflictListArray error:&conflictFixError]) {
NSLog(@"Unresolved conflict error %@, %@", conflictFixError, [conflictFixError userInfo]);
NSLog(@"abort");
abort();
}
} }
Upvotes: 8
Reputation: 81
It's semisolving, perhaps :) For example, you have following code, that exists in N objects (each one of them are in separate thread and are created in same time (+-10ms)):
[coreObject addLinkedObject:linkedObject1];
Time for processing routine in context is approx 70ms. if you just set NSMergePolicy to (for example): NSOverwriteMergePolicy, you will have Last-In-Changes: only last object will add link, because each context are snapshot-in-memory of persistent store. Thus each snapshot are created in time moment of routine object creation. 70ms processing time lag cause that information of coreObject is too old, when you save it. In other words you will have only one saved link or Merging error. Of course, you can subscribe on NSManagedObjectContextObjectsDidChangeNotification but in this case you'll have N! subscribed relations or you can subscribe in star manner cross main context in main thread, but sometimes it didn't work (I'm using MagicalRecord, Copyright 2011 Magical Panda Software LLC.). My solution is to re-read critical coreObject just before save it as well as using suitable merge policy:
@synchronized (self) {
if ([context hasChanges]) {
if (needRefresh) {
[context refreshObject:coreObject mergeChanges:NO];
[coreObject addLinkedObject:linkedObject1];
}
NSError *err = nil;
[context save:&err];
if (err) {
NSLog(@"Error Saving Linked Object: %@", [err userInfo]);
[context rollback];
}
}
}
In this case risk is minimal.
Upvotes: 2
Reputation: 16973
A merge conflict sometimes results when your database gets changed from two different places, then saved from two different places; in certain cases, the changes might affect the same objects or properties, and Core Data doesn't automatically overwrite them, as that might destroy valuable data.
There are a few options:
Upvotes: 37