使用后台上下文时无法在不同上下文中的对象之间建立关系

Posted

技术标签:

【中文标题】使用后台上下文时无法在不同上下文中的对象之间建立关系【英文标题】:Can't establish a relationship between objects in different contexts when using a background context 【发布时间】:2018-12-31 12:12:08 【问题描述】:

我正在尝试通过后台上下文插入NSManagedObject,但出现此错误:

Illegal attempt to establish a relationship 'location' between objects in different contexts (source = <Image: 0x600002f81b80> (entity: Image; id: 0x600000f44fe0 <x-coredata:///Image/t8C3934D6-DCD7-4A7B-A69C-9C18334F7A942> ; data: 
    image = <ffd8ffe0 00104a46 49460001 01000048 00480000 ffe10058 45786966 00004d4d 002a0000 00080002 01120003 00000001 0001>;
    location = nil;
) , destination = <Location: 0x600002fb3020> (entity: Location; id: 0xd78dad45136e9365 <x-coredata://9CA497CF-69A8-44ED-8741-C75AF480446E/Location/p2> ; data: 
    images = "<relationship fault: 0x600000f44480 'images'>";
    location = "29.977646364835238,31.32489065578125";
))

我知道这个问题之前被问过好几次,我已经检查了一些答案,但我真的不知道我的代码缺少什么。这是我的代码:

func saveImagesToDb () 

            //Store the image in the DB along with its location on the background thread
            dataController.backgroundContext.perform 
                let imageOnMainContext = Image (context: self.dataController.viewContext)
                let imageManagedObjectId = imageOnMainContext.objectID
                let imageOnBackgroundContext = self.dataController.backgroundContext.object(with: imageManagedObjectId) as! Image

                for downloadedImage in self.downloadedImages 

                    let imageData = NSData (data: downloadedImage.jpegData(compressionQuality: 0.5)!)
                    imageOnBackgroundContext.image = imageData as Data
                    imageOnBackgroundContext.location = self.imagesLocation


                    try? self.dataController.backgroundContext.save ()
                
            


    

我只有两个实体,位置和图像。 Location 有一个名为 location 的属性,Image 有一个名为 image 的属性。它们之间存在一对多的关系(一个位置可以有许多图像)。

我知道每个上下文都保留了自己的NSManagedObjects 副本。这就是为什么在代码中,我首先根据视图上下文获取了一个 Image,获取了它的 id,然后使用该 id 在背景上下文中获取了一个 Image 对象。

我做错了什么?

我是 Core Data 的新手,所以如果能向我解释这里发生了什么以及如何解决它,我将不胜感激。

更新:问题出在imagesLocation 上,它建立在视图上下文之上,所以我只是使用它在背景上下文中的 ID 从它创建了一个相应的对象。之后,问题就解决了,但我的问题here 中的图像对象和关系也有问题。我可以解决这个问题,我发布了答案,你可以检查一下。

【问题讨论】:

问题可能在于您的行将 imageOnBackgroundContext 上的位置设置为 self.imagesLocation。该 imagesLocation 变量可能在不是您的 backgroundContext 的上下文中保存一个 NSManagedObject。 @FJdeBrienne 是的,你是对的,imagesLocation 的值是在主线程上创建的位置。我使用 ID 在背景上下文中创建了一个 Location 对象,就像我对 Image 对象所做的那样,它可以工作,但是我遇到了另一个错误,可能会发布另一个问题。您能否发表您的评论作为答案,以便我接受并更新我的问题?感谢您的帮助 谢谢,我写了答案。 【参考方案1】:

似乎self.imagesLocation 是在外部线程上创建的 NSManagedObject,因此不能分配给imageOnBackgroundContext

您应该在您的backgroundContext 中使用NSManagedObjectID 获取self.imagesLocation 指向的对象,并将该获取的对象分配给您的imageOnBackgroundContext

【讨论】:

以上是关于使用后台上下文时无法在不同上下文中的对象之间建立关系的主要内容,如果未能解决你的问题,请参考以下文章

非法尝试在不同上下文中的对象之间建立关系“对象”

NSInvalidArgumentException:非法尝试在不同上下文中的对象之间建立关系

为啥我会得到:非法尝试在不同上下文中的对象之间建立关系...

单一上下文但“非法尝试在不同上下文中的对象之间建立关系‘xyz’

为啥我的产品->存档因“非法尝试在不同上下文中的对象之间建立关系”压缩类型“而失败?

核心数据:非法尝试建立关系+(空)上下文