2010-12-10 2 views
15

Иногда у меня есть эта ошибка с coredata в том же месте. Иногда это нормально, и в другое время у меня есть эта ошибка. Что это значит? Я не могу найти ничего об этом :(Ошибка iPhone Coredata (NSMergeConflict для NSManagedObject)

п.с. извините за мой английский :)

conflictList = ( «NSMergeConflict (0xd447640) для NSManagedObject (0xd41b370) с ObjectId '0xd41b500' с oldVersion = 4 и newVersion = 5 и старый снимок объекта = {\ 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 онлайн = 1; \ n фото = \ "\"; \ 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 (объект: Photo; id: 0xd431570; данные: {\ 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 (объект: WallReply; id: 0xd448270; data:) \ n)} \ "; \ n wallSender = \" {(\ n)} \ "; \ n} и новая кэшированная строка = {\ 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 онлайн = 1 ; \ n фото = \ "\"; \ 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} " );

ответ

31

Иногда возникает конфликт слияния, когда ваша база данных изменяется из двух разных мест, а затем сохраняется из двух разных мест; в некоторых случаях изменения могут влиять на одни и те же объекты или свойства, а Core Data автоматически не перезаписывает их, поскольку это может привести к разрушению ценных данных.

Есть несколько вариантов:

  • Когда вы получаете слияния конфликта, перебирать его информации, и вручную разрешить любые конфликты в соответствии с потребностями вашего приложения.
  • Set the merge policy контекст (ов) управляемого объекта, который будет автоматически разрешать определенные конфликты. Некоторые политики слияния являются частично разрушительными, некоторые из них очень разрушительны - что действительно правильно, зависит от вашего приложения и важности сохранения данных.
  • Используйте mergeChangesFromContextDidSaveNotification: для быстрой и тесной интеграции изменений в контексты управляемых объектов, которые еще не были сохранены.Обратите внимание, что это может по-прежнему требовать определенного уровня разрешения конфликтов, но должно помочь свести к минимуму серьезность.
+0

Ok, я думаю, я нашел причину этой ошибки. В некоторых методах я вставляю json-данные в coredata, используя for (id * in *), где я устанавливаю множество атрибутов и отношений с объектами. и только после этого я сохраняю контекст. Теперь я вставил [context save: & error] в конец «for», и я больше не вижу ошибок :) – ruffnecktsk 2010-12-10 06:42:15

1

Это semisolving, возможно :) Например, вы следующий код, который существует в N объектов (каждый из них в отдельном потоке и созданы в то же время (+ -10ms)):

[coreObject addLinkedObject:linkedObject1]; 

Время обработки в контексте составляет около 70 мс. , если вы только установили NSMergePolicy (например): NSOverwriteMergePolicy, у вас будут Last-In-Changes: только последний объект будет добавлять ссылку, потому что каждый контекст является снимком в памяти постоянного хранилища. Таким образом, каждый моментальный снимок создается в момент создания рутинного объекта. 70 мс время задержки обработки приводит к тому, что информация coreObject слишком старая, когда вы ее сохраняете. Другими словами, у вас будет только одна сохраненная ссылка или Ошибка объединения. Конечно, вы можете подписаться на NSManagedObjectContextObjectsDidChangeNotification, но в этом случае у вас будет N! подписанные отношения, или вы можете подписаться по звездной манере в основном контексте в основном потоке, но иногда это не сработало (я использую MagicalRecord, Copyright 2011 Magical Panda Software LLC.). Мое решение перечитывать критической coreObject непосредственно перед сохранить его, а также с помощью соответствующей политики слияния:

@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]; 
      } 
     } 
} 

В этом случае риск минимален.

8

Я получил тот же конфликт слияния, сохраняя контекст. см яблоко Doc here

Я решил конфликты с помощью NSMergePolicy

- (BOOL)resolveConflicts:(NSArray *)list error:(NSError **)error 

набор policyType к NSOverwriteMergePolicyType при создании объекта NSMergePolicy

NSOverwriteMergePolicyType: Определяет политику, которая переписывает состояние в постоянном хранилище для измененные объекты в конфликте.

`

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(); 
    } 
    } } 
6

Короче - включить Merge политики добавить к вашей установке МОС:

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 
}() 
Смежные вопросы