swift - NSManagedObjectID 与自定义 UUID 标识符属性 - 获取性能
问题描述
我真的很想避免使用NSManagedObjectID
将我的模型结构连接到它们的 CoreData 对象的方法。我的意思是这样的:
假设我Book
在 CoreData 中有一个实体,然后我有一个像这样的模型结构来代表我的模型层:
struct BookModel {
let name: String
...
let objectID: NSManagedObjectID // I need this to refer back to the entry in the database
}
我不喜欢这种方法。它使使用结构变得乏味,例如,测试很烦人,因为我总是必须生成虚拟 objectId 或使其成为BookModel.objectID
可选的。
我希望拥有的是实体内部的id
类型属性。这将很容易连接到结构,并且还允许结构在没有数据库的情况下正确存在:UUID
Book
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
属性不是一个好主意?我真的很感激对此的任何见解!
解决方案
我不会依赖NSManagedObjectID
你的代码中的。它使您的代码依赖于 Apple 的数据库实现,该实现可能随时更改,并且不会使您的应用程序对未来的更改具有弹性。
例如,您将无法使用新的NSPersistentCloudKitContainer
. 它不支持NSManagedObjectID
:请参阅https://developer.apple.com/documentation/coredata/mirroring_a_core_data_store_with_cloudkit/creating_a_core_data_model_for_cloudkit
NSManagedObjectID
正如您所建议的,您最好为实体提供唯一的 UUID,而不是硬编码。这可能会或可能不会影响性能,但从长远来看,您的情况会更好,因为底层核心数据库技术将会发生变化。
推荐阅读
- sql - 如何使用最大函数postgresql获取最大值的列名?
- javascript - 如何在浏览器工具栏旁边的 chrome 扩展中的 default_icon 上设置通知(徽章)?
- rust - GDB 无法识别 Rust 源
- spring - ControllerLinkBuilder/UriComponentsBuilder 不处理标头转发属性
- java - 防止在脚本调用时执行恶意输入
- javascript - 在javascript中的字符串中的每个特殊字符之前添加一个字符
- nginx - 将 localhost:3000 更改为子域地址
- swift - Swift 5 track CLLocation 当前位置点
- amazon-web-services - 如何一键修复导致 Nessus 漏洞扫描的服务器的所有关键问题?
- html - 是否可以将变量从 HTML (index.html) 发送到 Reactjs?