在iPhone上为Core Data程序创build一个唯一的ID

我有点烦恼搞清楚这个核心数据的东西。 如何创build一个具有唯一ID的新条目? 在SQL中,我只是将一个字段声明为一个自动增量字段。 我在这里没有看到类似的东西,但是我可能会错过一些东西。 我只是想要一个自动增加NSInteger字段,所以当我手动添加项目到数据库,我会有一些forms的参考。

虽然我同意你所说的,但核心数据背后还有一个身份validation机制。 ID确实由Core-Datapipe理,但是您可以通过以下方式检索它们:

NSManagedObjectID *moID = [managedObject objectID]; 

有关更多信息,请参阅: 核心数据编程指南

这不是CoreData的工作原理。

在CoreData中,创build实体的实例。 每个实例都是唯一的。 然后根据需要检索和操作实例。 CoreData负责为您的持久性,包括唯一标识实例。

从传统关系型数据库的所有知识中脱身。

从这里开始

然后去这里

具体来说, 这个 。

CoreData是一个非常强大的技术,它提供的function远远超出数据库一样的持久性。 它会为您节省许多代码,并且如果您拥抱它,performance会非常好。

这个类的函数将为你的id属性返回下一个可用的数字 (它必须是整型属性)。

我把它称为自动增量值生成器。 我仍然同意其他人对此有objectID,但有时你只需要数字。

你可以把这个函数放在实体的NSManagedObject子类中:

 +(NSNumber *)nextAvailble:(NSString *)idKey forEntityName:(NSString *)entityName inContext:(NSManagedObjectContext *)context{ NSFetchRequest *request = [[NSFetchRequest alloc] init]; NSManagedObjectContext *moc = context; NSEntityDescription *entity = [NSEntityDescription entityForName:entityName inManagedObjectContext:moc]; [request setEntity:entity]; // [request setFetchLimit:1]; NSArray *propertiesArray = [[NSArray alloc] initWithObjects:idKey, nil]; [request setPropertiesToFetch:propertiesArray]; [propertiesArray release], propertiesArray = nil; NSSortDescriptor *indexSort = [[NSSortDescriptor alloc] initWithKey:idKey ascending:YES]; NSArray *array = [[NSArray alloc] initWithObjects:indexSort, nil]; [request setSortDescriptors:array]; [array release], array = nil; [indexSort release], indexSort = nil; NSError *error = nil; NSArray *results = [moc executeFetchRequest:request error:&error]; // NSSLog(@"Autoincrement fetch results: %@", results); NSManagedObject *maxIndexedObject = [results lastObject]; [request release], request = nil; if (error) { NSLog(@"Error fetching index: %@\n%@", [error localizedDescription], [error userInfo]); } //NSAssert3(error == nil, @"Error fetching index: %@\n%@", [error localizedDescription], [error userInfo]); NSInteger myIndex = 1; if (maxIndexedObject) { myIndex = [[maxIndexedObject valueForKey:idKey] integerValue] + 1; } return [NSNumber numberWithInteger:myIndex]; } 

看看: [[NSProcessInfo processInfo] globallyUniqueString]

Apple文档:进程的全局标识。 该ID包括主机名,进程ID和时间戳,确保该ID对于networking是唯一的,如果不希望人们猜测该ID,则这是方便的。

以下是CoreData对象的三种唯一ID表示:

 NSManagedObjectID *taskID = [task objectID]; NSURL *taskUniqueURLKey = task.objectID.URIRepresentation; NSString *taskUniqueStringKey = task.objectID.URIRepresentation.absoluteString; 

!!!!注意:如果你想使用上面的唯一键作为索引,请确保对象在使用前保存到上下文,否则对象ID将是一个临时ID,稍后将被replace(例如保存后)。 查看NSManagedObjectID类的apple文档:

 - (BOOL)isTemporaryID; // indicates whether or not this ID will be replaced later, such as after a save operation (temporary IDs are assigned to newly inserted objects and replaced with permanent IDs when an object is written to a persistent store); most IDs return NO 

如果我们要与远程数据库进行同步,那么确实需要使用自动增加的id来存储唯一的数据行呢? 有没有一种方法来实现自动增量的ID,如果我们需要的话。 我知道核心数据不是必需的,但我需要从远程数据库导入数据,然后再次上传,并确保ID完好无损。

我认为在这样的条件下这将是有用的。

http://lists.apple.com/archives/cocoa-dev/2006/Jul/msg01801.html我们可以得到maxExistingID。; 所以当我们保存一个新的项目时我们可以增加

在Swift中更新到@Lukasz的答案:

 static func nextAvailble(_ idKey: String, forEntityName entityName: String, inContext context: NSManagedObjectContext) -> Int { let fetchRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest(entityName: entityName) fetchRequest.propertiesToFetch = [idKey] fetchRequest.sortDescriptors = [NSSortDescriptor(key: idKey, ascending: true)] do { let results = try context.fetch(fetchRequest) let lastObject = (results as! [NSManagedObject]).last guard lastObject != nil else { return 1 } return lastObject?.value(forKey: idKey) as! Int + 1 } catch let error as NSError { //handle error } return 1 } 

核心数据用于持久性框架,该框架抽象出主键。

每个NSManagedObject都有自己的唯一键,在其objectID属性中可用。

这个id在内部用来链接实体关系。 不需要像在SQL中一样将自己的ID保留为主键。

你总是可以通过NSManagedObject.objectID得到id。 并使用NSMananagedObjectContext.objectWithId获取对象上下文