【发布时间】:2011-06-10 20:22:16
【问题描述】:
假设我有一个存储在 Core Data 中的书籍列表。我想通过它的主键 ID 搜索一本书。
我知道 Core Data 创建的 sqlite 文件在每个表中都有一个 ID 列,但这似乎并没有暴露给我。
有人有什么建议吗?
【问题讨论】:
标签: iphone xcode core-data nspredicate nsmanagedobject
假设我有一个存储在 Core Data 中的书籍列表。我想通过它的主键 ID 搜索一本书。
我知道 Core Data 创建的 sqlite 文件在每个表中都有一个 ID 列,但这似乎并没有暴露给我。
有人有什么建议吗?
【问题讨论】:
标签: iphone xcode core-data nspredicate nsmanagedobject
-[NSManagedObject objectID] 是 Core Data 中对象实例的唯一 ID。可以通过-[NSManagedObjectID URIRepresentation]进行序列化。您可以使用-[NSPersistentStoreCoordinator managedObjectIDForURIRepresentation:] 从持久存储协调器中检索objectID,然后使用-[NSManagedObjectContext objectWithID:] 从托管对象上下文中获取对象。
但是
您应该记住,Core Data 不是 ORM。这是一个object graph management framework。那就是使用 SQLite(和唯一的行 ID)作为后端纯粹是一个实现细节。您越早摆脱 SQL/RDBMS 思维模式,您就越快对 Core Data 感到满意。与其尝试从存储的 ID 中查找对象,不如考虑为什么需要该对象以及什么对象需要它。如果Foo 类的实例需要能够访问Bar 类的实例,为什么不创建从Foo 到Bar 的关联并将适当的Bar 实例设置为目标在适当的Foo 实例上的关联。让 Core Data 跟踪对象 ID。
【讨论】:
正如 Barry Wark 所说,永远记住 Core Data 不是一个规范。纯 SQL 细节不会暴露给用户,每一行都只是一个对象。顺便说一句,有时您应该需要访问“主键”,例如当您需要将 coredata db 与外部 sql 数据库同步时(在我的情况下,我需要在回调函数中使用它来在 INSERT 之后更改对象的状态它在远程数据库中成功)。在这种情况下,您可以使用:
objectId = [[[myCoredataObject objectID] URIRepresentation] absoluteString]
这将返回一个字符串,如:x-coredata://76BA122F-0BF5-4D9D-AE3F-BD321271B004/Object/p521,这是 Core Data 用来识别该对象的唯一 ID。
如果您想取回具有该唯一 ID 的对象:
NSManagedObject *managedObject = [managedObjectContext objectWithID:[persistentStoreCoordinator managedObjectIDForURIRepresentation:[NSURL URLWithString:objectId]]];
注意:请记住,如果接收者尚未保存在 CoreData 上下文中,则对象 ID 是一个临时值,将在保存对象时更改。
【讨论】:
这是您可以使用Swift 从NSManagedObject 获取object id 为String 的方式:
entity.objectID.uriRepresentation().absoluteString
【讨论】: