Ошибка iPhone Coredata (NSMergeConflict для NSManagedObject)

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

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

conflictList = (          "NSMergeConflict (0xd447640) для NSManagedObject (0xd41b370) с объектным идентификатором" 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 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 фото Number = 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; данные: {\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 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 университет = 0;\n universityName = \" \ ";\n wallPostsCount = 0;\n}"     );

Ответы

Ответ 1

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

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

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

Ответ 2

Я получил тот же конфликт слияния, сохраняя контекст. см. apple doc здесь

Я разрешил конфликты, используя 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();
    }
  } }

Ответ 3

Вкратце - включите Merge Policy, добавьте это в свою настройку MOC:

objective-C

[_managedObjectContext setMergePolicy:[[NSMergePolicy alloc] initWithMergeType:NSMergeByPropertyObjectTrumpMergePolicyType]];

Свифта

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

Ответ 4

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

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

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