非法企图在不同背景下的对象之间build立“xyz”关系
我使用Apple的CoreDataBooks
示例应用程序作为在后台将数据拉入辅助pipe理对象上下文的基础,然后将这些数据合并到主pipe理对象上下文中。
我正在使用的数据是一个与Owner
实体(称为“所有者”)具有一对一关系的Book
实体。 Owner
实体与Book
(称为“书”)具有多对多的关系。
我的数据是一个XML格式的文档:
<Owner> <Name>alexpreynolds</Name> <ID>123456</ID> </Owner> <Books> <Book>Book One</Book> <Book>Book Two</Book> ... <Book>Book N</Book> </Books>
Book One
通过Book N
与一个Owner
( "alexpreynolds, 123456"
)相关联。
我将它parsing成一个Owner
实例和一个由Book
实例组成的NSMutableSet
。
当我第一次尝试保存时,它保存的很好,合并的数据显示在表格视图中。
然而,在第二次保存时,当XML内容包含新书时,它不起作用。
以下是发生的事情:
然后我尝试加载一个XML文档,其中包含一个尚未在主pipe理对象上下文中的Book
。 新Book
使用与其他Book
相关联的Owner
。
我有挑选出这个唯一的Owner
pipe理对象(我已经在我的主要pipe理对象上下文中)和主要MOC中找不到唯一的Book
例程。
由此,我在二级商务部创build了一个新的Book
对象,并将其“ owner
”关系设置为指向我在主要商业机构中find的唯一Owner
。
当我保存时,我得到以下错误:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Illegal attempt to establish a relationship 'owner' between objects in different contexts (source = <Book: 0x7803590> (entity: Book; id: 0x7802ae0 <x-coredata:/// Book/t527F06B2-3EB5-47CF-9A29-985B0D3758862> ; data: { creationDate = 2009-10-12 06:01:53 -0700; name = nil; nameInitial = nil; operations = ( ); owner = nil; type = 0; }) , destination = <Owner: 0x78020a0> (entity: Owner; id: 0x3a56f80 <x-coredata://043AF2F0-1AD0- 4078-A5E8-E9D7071D67D1/Owner/p1> ; data: { books = "<relationship fault: 0x7801bf0 'books'>"; displayName = alexpreynolds; ownerID = 123456; }))'
如何在二级商务部创build一个新的Book
实体,以便我还可以将其与主要商务部的先前Owner
联系起来?
您不能在不同的托pipe对象上下文中的对象之间build立关系。 所以解决这个问题的一种方法就是将对象放入托pipe对象上下文中。
例如:
NSManagedObject *book = // get a book in one MOC NSManagedObject *owner = // get an owner in a different MOC [[owner mutableSetValueForKey:@"books"] addObject:[owner.managedObjectContext objectWithID:[book objectID]]];
所以你所做的实际上是将这Book
与owner
一起提交到相同的托pipe对象上下文中。 请记住,这只有在book
已经保存的情况下才可能。 托pipe对象上下文将在持久性存储中查找对象,因此必须先保存该对象。
我有同样的问题,这句话帮助我解决了这个错误。
您不能在不同的托pipe对象上下文中的对象之间build立关系。 所以解决这个问题的一种方法就是将对象放入托pipe对象上下文中。
这里是我的代码(我replace了这些variables来使它适合你):
// Have the owner object and get the managedObjectContext Owner *owner = [[DataFunctions alloc] getCurrentOwner]; NSManagedObjectContext *context = [owner managedObjectContext]; // Create a book and use the manageObjectContext of owner Book *book = [NSEntityDescription insertNewObjectForEntityForName:@"Book" inManagedObjectContext:context]; [newQuote setValue: "Book Title" forKey:@"title"]; [newQuote setOwner:owner];
我希望这有帮助 :)
在这里,你正试图build立一个关系,这个关系是用不同的上下文获取/创build的。 核心数据不会让你build立这样的关系。 为了达到这个目的,你应该使用objectID获取第一个对象的上下文(你试图build立关系)。 现在你应该能够build立这两个对象之间的关系。 例如:
MagicalRecord.saveWithBlock({[unowned self] (localContext: NSManagedObjectContext!) in let user = User.MR_createEntityInContext(localContext)! ..... ..... }) //here local context stores data on end of block itself MagicalRecord.saveWithBlock({[unowned self] (localContext: NSManagedObjectContext!) in let address = Address.MR_createEntityInContext(localContext)! ..... ..... let user = localContext.objectWithID(self.user!.objectID) as! User user.address = address })
希望对你有帮助!
正如错误所述,不允许在一个核心数据对象中有一个关系,这个对象的值被设置为另一个上下文中保存的另一个对象。 解决这个问题的一个方法是等到保存新对象并将其合并回主要上下文之后,然后设置owner
关系(因为两个对象现在都在相同的上下文中,所以没有问题) 。
book *book = [mainContext ........] //Get book from default context NSManagedObjectID *objectId = [book objectID]; Book *tmpBook = [tmpContext objectWithID:objectId]; //Now book has the legal relationship