我真的很想避免使用 NSManagedObjectID
作为将我的模型结构连接到它们的 CoreData 对象的一种方式。我的意思是这样的:
假设我有一个 Book
CoreData 中的实体,然后我有一个像这样的模型结构,代表我的模型层:
struct BookModel {
let name: String
...
let objectID: NSManagedObjectID // I need this to refer back to the entry in the database
}
我不喜欢这种方法。它使处理结构变得乏味,例如,测试很烦人,因为我总是必须生成虚拟 objectIds 或 make 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。执行时间差异显着:
With ObjectID: 0.015282376s
With UUID: 1.093346287s
然而,奇怪的是第一种方法实际上并没有产生任何 SQL 查询(我使用启动参数
-com.apple.CoreData.SQLDebug 4
记录了它们)。这可以解释速度,但不能解释为什么它根本不需要与数据库通信。我研究了一下,但无法真正弄清楚是什么
object(with: NSManagedObjectID)
实际上在幕后。这是否意味着,使用“自定义”
UUID
属性(property)不是个好主意吗?我真的很感激任何对此的见解!
最佳答案
我不会依赖 NSManagedObjectID
在你的代码中。它使您的代码依赖于 Apple 的数据库实现,该实现可能随时更改,并且不会使您的应用程序对 future 的更改具有弹性。
例如,您将无法使用新的 NSPersistentCloudKitContainer
.不支持 NSManagedObjectID
:见 https://developer.apple.com/documentation/coredata/mirroring_a_core_data_store_with_cloudkit/creating_a_core_data_model_for_cloudkit
而不是硬编码 NSManagedObjectID
正如您所建议的,您最好为您的实体提供唯一的 UUID。这可能会也可能不会影响性能,但从长远来看,您的情况会更好,因为底层核心数据库技术将发生变化。
关于swift - NSManagedObjectID 与自定义 UUID 标识符属性 - 获取性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60990596/