【问题标题】:Can I pass NSManagedObject into performBackgroundTask safely?我可以安全地将 NSManagedObject 传递给 performBackgroundTask 吗?
【发布时间】:2018-01-10 11:52:11
【问题描述】:

主题中的问题。我有一组名为reports 的NSManagedObjects 子类。现在我想对这些数据进行大量计算。这可能需要一些时间,所以我不想阻塞主线程。

let persistentContainer = DatabaseStack.shared.persistentContainer
persistentContainer.performBackgroundTask { (context) in
    //HERE: calculation on reports array
}

我是否应该使用给定的背景 context 重新获取 performBackgroundTask 内的 reports 数组。哪种重新获取方法是最好的?能给我举个例子吗?

编辑

我知道NSManagedObjects 不是线程安全的,但我在iOS10 下开发,我使用performBackgroundTask 方法。我想知道那里的方法是否没有处理它

EDIT2

我补充说,现在一切正常(我不重新获取对象),但我想确定这将始终有效,不会发生随机崩溃。

【问题讨论】:

    标签: swift multithreading core-data io


    【解决方案1】:

    这仍然不安全。文档在最新文章中明确说明了这一点,描述了并发和队列:

    NSManagedObject 实例不打算在 排队。这样做可能会导致数据损坏和终止 的应用程序。需要移交托管对象时 从一个队列到另一个队列的引用,必须通过 NSManagedObjectID 实例。

    您可以通过调用 NSManagedObject 实例上的 objectID 方法。

    https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CoreData/Concurrency.html(在底部)

    使用 perform 之类的方法假设您确实使用上下文实现了原子操作(例如,创建 MO 并保存它们或获取 MO 并为请求逻辑提取数据等)

    【讨论】:

    • 好的,那么当对象已经被获取并且我想在不阻塞主线程的情况下对其进行一些计算时该怎么办?
    • @KamilHarasimowicz,这取决于您是否要保存计算更改。如果在计算后应保存更改,您只需在 pefromBackgroundTask 块内完成所有操作。此方法保证将为该任务创建一个私有队列上下文,并且您不会阻塞主队列。因此,只需获取、计算、修改 MO、保存上下文。如果您需要在另一个队列中进行计算,只需提取您需要的数据并转发即可。在不同的上下文之间传递 MO 实例是不安全的,但是在相同的上下文中使用它是节省的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-17
    • 2017-10-09
    相关资源
    最近更新 更多