2013-03-17 3 views
1

У меня возникли проблемы с Core Data + параллельными/вложенными MOC (не знаю, с какими из них возникают проблемы с = P).EXC_BAD_ACCESS при попытке получить доступ к объекту управляемого объекта

У меня есть метод, в котором я передаю идентификатор управляемого объекта (я проверил его постоянный), и этот метод имеет контекст дочернего управляемого объекта, который ограничен определенной очередью. Я могу получить объект из контекста управляемого дочернего объекта через [managedObjectContext objectWithID:moID], но когда я пытаюсь получить доступ к любому из его свойств (управляемый объект по-прежнему является ошибкой), я получаю EXC_BAD_ACCESS со следами стека, показывающими _svfk_1 и objc_msgSend.

Я знаю, что трудно понять, в чем проблема, без образца кода, но я надеялся, что кто-то может пролить свет на возможные причины. Благодарю. =)

EDIT: Я попытался с помощью existingObjectWithID:error: вместо objectWithID:, как предположил Том Харрингтон, и теперь он работает иногда, но не работает в других случаях. Я также испытал авария EXC_BAD_ACCESS на mergeChangesFromContextDidSaveNotification:. Я подозреваю, что это может быть проблема синхронизации. Если я что-то редактирую в одном контексте и сохраняю, пока что-то еще редактируется в моем дочернем контексте, это может вызвать проблему?

EDIT 2: Я понял, почему existingObjectWithID: ошибка: работала иногда, но не всегда. Идентификатор управляемого объекта действительно был временным идентификатором (не должен mergeChangesFromContextDidSaveNotification: конвертировать его в постоянный ID?), Поэтому мне нужно было позвонить obtainPermanentIDsForObjects:error: перед передачей ID. Но я по-прежнему получаю аварийные ситуации в детском контексте mergeChangesFromContextDidSaveNotification:. Каковы могут быть возможные причины этого? Благодарю.

EDIT 3: Вот как выглядит моя иерархия MOC.

Persistent Store Coordinator 
       | 
     Persistent Store MOC 
     /   \ 
Main Queue MOC Child MOC (confinement) 

Я вызов методы из основной очереди, который использует ребенок MOC (в другой очереди) для вставки и обновления некоторых управляемых объектов и в то же время, я вставка и обновление управляемых объектов в Постоянный магазин MOC. Управляемые объекты также могут обновляться, удаляться и вставляться в MOC основного очереди одновременно. Я объединять любые изменения от Координатора постоянных хранилищ как к Главному Очереди MOC, так и к MOC для детей.

Еще несколько вопросов: Сохраняет ли MOC автоматическое слияние вещей? Если есть ожидающий запрос слияния для MOC и вы сохраняете до того, как этот запрос слияния будет обработан, могут ли это возникнуть проблемы?

EDIT 4: Вот как я инициализирую MOC ребенка.

dispatch_sync(_searchQueue, ^{ 
    _searchManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSConfinementConcurrencyType]; 

    [_searchManagedObjectContext setParentContext:_persistentStoreManagedObjectContext]; 
    [_searchManagedObjectContext setMergePolicy:NSMergeByPropertyStoreTrumpMergePolicy]; 
}); 

Btw, я заметил, что слияние только выходит из строя (с EXC_BAD_ACCESS), когда уведомление содержит удаленные объекты.

+1

О: «Предполагается, что данные в постоянном хранилище, представленном objectID, существуют - если это не так, возвращаемый объект выдает исключение при доступе к любому свойству (то есть при сбое ошибки)». Позвольте мне проверить это. – fumoboy007

+0

Нет, я добавил точку останова в 'prepareForDeletion' в моем подклассе управляемых объектов, но он никогда не запускался. Таким образом, управляемый объект не был удален, когда я вызываю этот метод. – fumoboy007

+0

Вы используете performBlock, чтобы поговорить с дочерним MOC (предположим, что это не в главной очереди)? –

ответ

0

Я нашел исправление. Перед каждым сохранением я делаю [moc obtainPermanentIDsForObjects:[[moc insertedObjects] allObjects] error:&error]. Теперь я больше не получаю сбоев.

Я все еще немного мрачен от того, что именно происходит, но вот мое понимание. При сохранении вновь вставленных объектов им присваивается только постоянный идентификатор, когда MOC, связанный с координатором постоянного хранилища, сохраняет. Теперь либо mergeChangesFromContextDidSaveNotification: размножал постоянные идентификаторы обратно (как я и ожидал), а какая-то другая операция произошла непосредственно перед слиянием или где-то произошла ошибка Apple. В любом случае, получение постоянных идентификаторов заранее решило проблему.

TL; DR Основные данные + параллелизм сложны.

1

Похоже, вы все еще слишком много работаете. Для вашего ребенка MOC, так как он находится в последовательной очереди, используйте NSPrivateQueueConcurrencyType и установите родительский элемент в свой основной MOC.

NSConfinementConcurrencyType предназначен для устаревших конфигураций.

Смежные вопросы