0

Может кто-нибудь объяснить, почему дал следующий MagicalRecord код импортаEXC-BAD-ACCESS при установлении отношений между двумя объектами

__block NSManagedObject *importedObject = nil; 

[MagicalRecord saveWithBlockAndWait:^(NSManagedObjectContext *localContext) { 
    id entityClass = NSClassFromString(name); 
    importedObject = [entityClass importFromObject:dictionary inContext:localContext]; 
}]; 

NSManagedObjectID *importedObjectID = importedObject.objectID; 

NSManagedObject *relatedObject = ((CustomRelatedExampleObject *) [[NSManagedObjectContext defaultContext] objectWithID:importedObjectID]).relatedObject; 

Это прекрасно работает, устанавливая отношения и сохранение, как и ожидалось

[MagicalRecord saveWithBlockAndWait:^(NSManagedObjectContext *localContext) { 
     someObjectInDefaultContext.alsoRelated = relatedObject; 
}]; 

Но это приводит к неправильному доступу к exec, когда я ожидал, что это технически более правильно, потому что я использую локальный контекст для сохранения моих данных. (Примечание: я ушел из кода, который получает ObjectIds от обоих объектов для краткости)

[MagicalRecord saveWithBlockAndWait:^(NSManagedObjectContext *localContext) { 
     AnotherCustomExampleObject *localSomeOtherObjectInDefaultContext = (AnotherCustomExampleObject *) [localContext objectWithID:someOtherObjectInDefaultContextObjectID]; 
     CustomRelatedExampleObject *localRelatedObject = (CustomRelatedExampleObject *) [localContext objectWithID:localRelatedObjectID]; 
     localSomeOtherObjectInDefaultContext.alsoRelated = localRelatedObject; 
}]; 

Я получаю EXEC плохой доступ на последней строке, когда я пытаюсь присвоить объект отношения в другом объекте.

UPDATE 1

Эта проблема была вызвана использованием временных идентификаторов объектов при получении локальных копий объектов в другом управляемом контексте объекта.

UPDATE 2

Я обнаружил, что просто изменить метод, используемый для получения объекта удаляет ошибку.

[MagicalRecord saveWithBlockAndWait:^(NSManagedObjectContext *localContext) { 
    AnotherCustomExampleObject *localSomeOtherObjectInDefaultContext = (AnotherCustomExampleObject *) [localContext existingObjectWithID:someOtherObjectInDefaultContextObjectID]; 
    CustomRelatedExampleObject *localRelatedObject = (CustomRelatedExampleObject *) [localContext existingObjectWithID:localRelatedObjectID]; 
    localSomeOtherObjectInDefaultContext.alsoRelated = localRelatedObject; 
}]; 

using existingObjectWithID вместо objectWithID возвращает объект с постоянным идентификатором вместо временного.

ответ

1

Проверьте идентификатор объекта. Если один или оба являются временными, основным данным это не понравится. Но, в общем, крах, который вы описываете, состоит в том, что вы пытаетесь связать два объекта из другого контекста. Я знаю, что вы выполняете здесь правильные шаги, но, возможно, дважды проверьте в отладчике, чтобы убедиться, что контекст на этих объектах одинаковый.

+0

Благодаря casademora, кажется, что даже если контекст, в который импортируются объекты, сохраняется, у объектов действительно есть временные идентификаторы. Это связано с тем, что волшебная запись использует родительский контекст для фактического сохранения данных в хранилище. Поскольку я уже вынул идентификатор объекта из объекта, он не обновляется при сохранении родительского контекста. – nacross

+0

Я обновил вопрос после обнаружения способа обойти мою проблему, можете ли вы пролить свет на то, почему это работает? – nacross

+0

existingObjectWithID работает, потому что он возвращает объект из вашего текущего контекста. Недавно я столкнулся с этой проблемой и обновил MR_inContext: чтобы пройти все способы поиска объекта на основе идентификатора объекта. Взгляните в экспериментальную ветвь для этого. – casademora