这似乎很愚蠢,但我仍然不知道如何在xcdatamodel文件中将属性标记为主键。我的永久存储是sqlite文件。谁能帮我?
在这种情况下,如何“验证”一个唯一的ID?我应该写一个验证方法之类的吗?
Answers:
您的选择是:
-[NSManagedObject objectID]
。请注意,此ID是临时的,直到第一次保存对象或您调用-[NSManagedObjectContext obtainPermanentIDsForObjects:error:]
CFUUID
函数族为您的-awakeFromInsert
方法中的每个对象生成一个UUID没有很好的方法来验证属性是否唯一。您将获得的最接近的结果是确保它在创建时是唯一的,然后实现一个自定义的setter方法,该方法将阻止任何更改ID的人。
请记住,Core Data是一个对象图持久性框架,而不是数据库。诸如主键之类的事物被抽象掉了,因为它们取决于持久性存储的实现。
有时在黑客时需要主键的实际整数。这是一个可以抓住它的方法:
NSManagedObjectID *yourManagedObjectID = [yourManagedObject objectID];
int yourManagedObject_PK = [[[[[yourManagedObjectID URIRepresentation] absoluteString] lastPathComponent] substringFromIndex:1] intValue];
尽管CoreData是一个对象图,但是如果查看CoreData生成的SQLite数据库数据,这种获取NSManagedObject主键的方法应该不是问题。ii在相同的代码中一起使用了CoreData和低级sqlite3 C库,并将主键从CoreData传递到sqlite3来获取记录也很好。
!如果您打算在生产中使用此代码,请注意对数据库主键转换为URIRepresentation的方式可能进行的内部更改,这可能会破坏您的代码。
请享用
一个快速扩展来检索主键
extension NSManagedObject {
var primaryKey : String {
guard objectID.uriRepresentation().lastPathComponent.count > 1 else { return "" }
return objectID.uriRepresentation().lastPathComponent.substring(from: 1)
}
}
对于字符串
extension String
{
func substring(from : Int) -> String {
guard self.count > from else { return "" }
return String(self[self.index(self.startIndex, offsetBy: from)...])
}
}
我宁愿使用时间+类名称作为唯一标识符。