NSManagedObjectID 与自定义 UUID 标识符属性 - 获取性能
Posted
技术标签:
【中文标题】NSManagedObjectID 与自定义 UUID 标识符属性 - 获取性能【英文标题】:NSManagedObjectID vs custom UUID identifier attribute - fetch performance 【发布时间】:2020-04-02 11:33:18 【问题描述】:我真的很想避免使用NSManagedObjectID
作为将我的模型结构连接到它们的CoreData 对象的一种方式。我的意思是这样的:
假设我在 CoreData 中有一个 Book
实体,然后我有一个像这样的模型结构来代表我的模型层:
struct BookModel
let name: String
...
let objectID: NSManagedObjectID // I need this to refer back to the entry in the database
我不喜欢这种方法。这使得使用结构变得乏味,例如,测试很烦人,因为我总是必须生成虚拟 objectId 或使 BookModel.objectID
可选。
我希望在Book
实体中拥有UUID
类型的id
属性。这将非常容易连接到结构,并且还允许结构在没有数据库的情况下正确存在:
struct BookModel
let name: String
...
let id: UUID
...
func object() -> Book
// Retrieve managed object using a fetch request with a predicate.
我注意到您实际上可以在实体中拥有UUID
属性。但是,性能差异似乎是巨大的。我创建了一个尝试获取单个对象 10000 次的示例。
首先,我使用context
s object(with: NSManagedObjectID)
获取它们。我将所有可能的 objectId 硬编码在一个数组中,并且每次都随机传递一个。
然后,我使用带有 NSPredicate
的简单获取请求,该请求传递了一个随机 UUID。
执行时间差异显着:
ObjectID:0.015282376s
使用 UUID:1.093346287s
然而,奇怪的是第一种方法实际上并没有产生任何 SQL 查询(我使用启动参数 -com.apple.CoreData.SQLDebug 4
记录它们)。这可以解释速度,但不能解释为什么它根本不需要与数据库通信。
我进行了一些研究,但无法真正弄清楚 object(with: NSManagedObjectID)
在幕后实际上做了什么。
这是否意味着使用“自定义”UUID
属性不是一个好主意?我非常感谢您对此的任何见解!
【问题讨论】:
【参考方案1】:我不会依赖您代码中的NSManagedObjectID
。它使您的代码依赖于 Apple 的数据库实现,这些实现可能随时发生变化,并且不会使您的应用对未来的变化具有弹性。
例如,您将无法使用新的NSPersistentCloudKitContainer
。不支持NSManagedObjectID
:见https://developer.apple.com/documentation/coredata/mirroring_a_core_data_store_with_cloudkit/creating_a_core_data_model_for_cloudkit
您最好按照您的建议,为您的实体提供唯一的 UUID,而不是硬编码 NSManagedObjectID
。这可能会或可能不会影响性能,但从长远来看,您的情况会更好,因为底层核心数据库技术将会发生变化。
【讨论】:
感谢您的意见。我不知道这个。我一直认为NSManagedObjectID
是 Core Data 的基本要素之一。以上是关于NSManagedObjectID 与自定义 UUID 标识符属性 - 获取性能的主要内容,如果未能解决你的问题,请参考以下文章
从一个上下文到另一个上下文使用 NSManagedObjectID 是不是安全?
在多个 NSPersistentStoreCoordinator-s 之间传递 NSManagedObjectID-s 是不是安全?