【问题标题】:Is it allowed to pass NSManagedObject through performBlock of the same NSManagedContext?是否允许通过相同 NSManagedContext 的 performBlock 传递 NSManagedObject?
【发布时间】:2020-01-31 16:40:04
【问题描述】:

我可以设置不同对象之间的关系执行相同的NSManagedContext的块吗?

我创建了一个私有上下文 并使用(只是示例):

let pContext = persistentContainer.newBackgroundContext()
pContext.perform {
   let user = pContext.fetch(<fetch Request>).first
   pContext.performAndWait {
        let book = pContext.fetch(<another fetch request>).first
        book.name = "skjkjd"
        pContext.save()
        book.author = user
        pContext.save()
   }
}

此代码会产生以下错误吗?在哪些情况下?

致命异常:NSInvalidArgumentException 非法尝试在不同上下文中的对象之间建立关系“作者”

【问题讨论】:

    标签: ios swift multithreading core-data


    【解决方案1】:

    如果我没记错的话,AppDelegate persistentContainer.viewContext 是一个单例。您不应该按照您尝试的方式跨线程传递 MOC。

    看看苹果文档:https://developer.apple.com/documentation/coredata/using_core_data_in_the_background

    尝试(未测试):

        let pContext = persistentContainer.newBackgroundContext()
        pContext.perform {
            let user = pContext.fetch(<fetch Request>).first
            let userObjcID = user.objectID
                pContext.performAndWait {
                     let book = pContext.fetch(<another fetch request>).first
                     book.name = "skjkjd"
                     // pContext.save()
                     book.author = pContext.object(with: userObjcID)
            pContext.save()
       }
    }
    

    【讨论】:

    • 私有上下文与串行队列相关联,因此文档说我们不能在不同队列(而不是线程)之间传递对象。但我在相同的私人环境中这样做。我在文档中没有找到任何关于不同线程(仅队列)的信息。也许私有上下文可以为不同的performBlock使用不同的队列?我还没有找到关于它的文档。
    • 好吧,如果您使用相同的上下文只是不同的 performBlocks,请使用 NSManagedObjectID,以获取 managedObject 从一个块到另一个块的引用
    • 谢谢,很高兴在文档中添加标记以避免此类问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-22
    • 2015-11-26
    • 2020-08-26
    • 2011-07-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多