我正在开发一种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()
}
}
}
答案 0 :(得分:2)
充其量很难提供涉及CoreData的API。
您不能仅在API中公开托管对象,因为这些对象绑定到库专用的特定线程或调度队列。您还需要客户端传递一个托管对象上下文,该上下文定义了客户端将在其中使用托管对象的执行上下文。
如果您的内部MOC和客户端的MOC不相同,则该API不可避免地会变为异步-否则它将阻塞线程。
您可能需要仅在主线程上使用此API,并且您的库也应注意使用相同的MOC。当然,这有两个缺点,可能使API异步只是其中之一。
由于您也不能强迫开发人员阅读文档,因此第一个使用您的API的开发人员可能不会从主线程调用它。 ;)
另一种替代方法是让客户端将闭包传递给API,然后在正确的执行上下文中从您的库中调用该闭包。这也使API变得异步,并且还要求开发人员对CoreData有深刻的理解,因为她获得了CoreData托管对象。
使用“ Swift”值的第一种方法可能是处理此问题的最佳方法。使CoreData成为您的库的“实现细节”,并为开发人员节省了使用CoreData时所涉及的麻烦。