CoreData-使用执行和后台线程获取NSManagedObject

时间:2018-12-31 08:16:55

标签: swift core-data nsmanagedobject

我正在开发一种SDK,它仅使用1个NSManagedObjectContext类型的privateQueueConcurrencyType

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

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

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

例如: 从结果中搜寻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()

        }
    }
}

1 个答案:

答案 0 :(得分:2)

充其量很难提供涉及CoreData的API。

您不能仅在API中公开托管对象,因为这些对象绑定到库专用的特定线程或调度队列。您还需要客户端传递一个托管对象上下文,该上下文定义了客户端将在其中使用托管对象的执行上下文。

如果您的内部MOC和客户端的MOC不相同,则该API不可避免地会变为异步-否则它将阻塞线程。

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

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

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

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