【问题标题】:CoreData - Fetch NSManagedObject with perform and background threadCoreData - 使用执行和后台线程获取 NSManagedObject
【发布时间】:2018-12-31 08:16:55
【问题描述】:

我正在开发一个 SDK,它只使用 1 个 NSManagedObjectContext,类型为 privateQueueConcurrencyType

为了获取对象,我使用perform(),然后将结果传递给闭包。

我从后台线程调用此方法,并在后台线程(可能与调用它的线程不同)上使用结果。

我知道在线程之间传递对象是不行的,但我对我今天处理它的方式并不满意。 我处理它的方式是,每个NSManagedObject 都映射到“普通”Swift 对象,然后我使用 swift 对象。

例如: Foreach NSManagedObject 从结果中创建新对象(不是NSManagedObject),然后我使用这些对象。

我想使用NSManagedObjects,而不是创建包含相似数据的新数据。

最好的方法是什么? 我还能使用 NSManagedObject 吗?

func getRecordsByPredicate<T: NSManagedObject>(type: T.Type, predicate: NSPredicate, success: @escaping (_ record: [T]?) -> Void, failure: @escaping () -> Void) {

    self.context.perform {
        let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: String(describing: type.self))
        fetchRequest.includesPropertyValues = false
        fetchRequest.predicate = predicate

        do {
            let results = try context.fetch(fetchRequest)
            success(results as? [T])
        } catch {
           print(error.localizedDescription)
           failure()

        }
    }
}

【问题讨论】:

    标签: swift core-data nsmanagedobject


    【解决方案1】:

    提供一个涉及 CoreData 的 API 充其量是困难的。

    您不能只公开 API 中的托管对象,因为它们与您的库私有的特定线程或调度队列相关联。您还需要客户端传递一个托管对象上下文,它定义了客户端将使用托管对象的执行上下文。

    如果你的内部 MOC 和客户端的 MOC 不一样,API 不可避免地会变成异步的——否则会阻塞线程。

    您可能要求此 API 只能在主线程上使用,并且您的库也要注意使用相同的 MOC。这当然有几个缺点,可能使 API 异步只是其中之一。

    由于您也不能强制让开发人员阅读您的文档,因此第一个使用您的 API 的开发人员可能不会从主线程调用它。 ;)

    另一种选择是让客户端将闭包传递给 API,然后在正确的执行上下文中从您的库中调用该闭包。这也使得 API 是异步的,并且还需要开发人员对 CoreData 有深入的了解,因为她获取的是 CoreData 托管对象。

    您使用“Swift”值的第一种方法可能是处理此问题的最佳方法。使 CoreData 成为您库的“实现细节”,并为开发人员省去使用 CoreData 时所涉及的麻烦。

    【讨论】:

    • 感谢您的回复。此 API 仅供内部使用,SDK 用户不会获取托管对象。有没有办法通过这个 API 在内部继续使用托管对象?
    • 如果 API 不是公开的,而只是一些在您的 SDK 内部使用的 API,您可以选择创建、选择和管理适当的托管对象上下文 外部 内部图书馆的一部分。然后,内部部分应该是“MOC 不可知论”,也就是说,它只使用从调用者那里获得的任何 MOC。不确定这在您的情况下是否可行。重要的是,SDK 用户不会看到托管对象。
    • 它如何帮助我从上下文中向 API 传递一个 MOC?你能分享一个例子吗?非常感谢!
    • 您的低级函数可能处理获取、排序、过滤等。使用高级函数提供的 MOC(在您的库中仍然是私有的)。只有更高级别知道应该将哪个上下文(例如私有上下文或与主线程关联的上下文)用于任务。但这是在设计库时做出的决定。我只建议用户看到一个只有普通结构和类的 API,例如不过,没有 CoreData 泄漏,很可能是异步的。
    猜你喜欢
    • 2021-10-19
    • 1970-01-01
    • 1970-01-01
    • 2012-06-26
    • 1970-01-01
    • 2017-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多