iPhone에서 Core Data 프로그램에 대한 고유 ID 생성
이 핵심 데이터 항목을 파악하는 데 약간의 문제가 있습니다. 고유 ID로 새 항목을 생성하려면 어떻게합니까? SQL에서는 하나의 필드를 자동 증가 필드로 선언합니다. 여기에는 그런 것이 보이지 않지만 뭔가 빠졌을 수 있습니다. 자동 증분 NSInteger 필드를 원하므로 데이터베이스에 항목을 수동으로 추가 할 때 항목에 대한 참조 형식을 갖게됩니다.
말씀하신 내용에 동의하지만 핵심 데이터 뒤에는 ID 메커니즘이 있습니다. ID는 실제로 Core-Data에서 관리하지만 다음을 사용하여 검색 할 수 있습니다.
NSManagedObjectID *moID = [managedObject objectID];
자세한 내용은 다음을 참조하십시오. 핵심 데이터 프로그래밍 가이드
CoreData가 작동하는 방식이 아닙니다.
CoreData에서 엔터티의 인스턴스를 만듭니다. 각 인스턴스는 고유합니다. 그런 다음 필요에 따라 인스턴스를 검색하고 조작합니다. CoreData는 고유하게 식별되는 인스턴스를 포함하여 사용자를 위해 지속성을 처리합니다.
기존의 관계형 데이터베이스에 대해 알고있는 모든 것에서 벗어나십시오.
CoreData는 데이터베이스와 같은 지속성 이상의 기능을 제공하는 놀랍도록 강력한 기술입니다. 많은 코드 줄을 절약 할 수 있으며 수용하면 매우 잘 수행됩니다.
이 클래스 함수는 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 및 타임 스탬프가 포함되어 ID가 네트워크에 대해 고유한지 확인합니다. 이는 사람들이 ID를 추측하지 않도록하는 데 유용합니다.
다음은 CoreData 객체의 고유 한 ID 표현의 세 종류입니다.
NSManagedObjectID *taskID = [task objectID];
NSURL *taskUniqueURLKey = task.objectID.URIRepresentation;
NSString *taskUniqueStringKey = task.objectID.URIRepresentation.absoluteString;
!!!! 참고 : 위의 고유 키를 인덱스로 사용하려면 객체를 사용하기 전에 컨텍스트에 저장했는지 확인하십시오. 그렇지 않으면 objectID가 나중에 대체 될 임시 ID가됩니다 (예 : 저장 후). NSManagedObjectID 클래스의 사과 문서를 참조하십시오.
- (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
What if we want to sync with a remote database that does need autoincremented id's for unique rows of data? Is there a way to implement autoincremented id's if we need to. I understand it's not required for core data but I need to import data from a remote database and then upload again and make sure the id's are intact.
i think this will be usefull in such conditions.
http://lists.apple.com/archives/cocoa-dev/2006/Jul/msg01801.html We can get maxExistingID . SO we can increment that when saving a new item
Update to @Lukasz answer in Swift:
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
}
Core data is used for persistance framework, this framework abstracts the primary key.
Each NSManagedObject has its own unique key built in which is available in its objectID property.
This id is internally used to link entities over its relations. There is no need to maintain an own id as a primary key as you are used to do in SQL.
You can always get the id by NSManagedObject.objectID. and fetching object context using NSMananagedObjectContext.objectWithId
'Program Tip' 카테고리의 다른 글
macOS Mojave에서 Xcode 10 네트워크 링크 조절기를 설치할 수 없음 (0) | 2020.12.13 |
---|---|
Ruby on Rails의 숨겨진 기능 (0) | 2020.12.13 |
자바 스크립트 : 하나의 값을 여러 값과 비교하는 가장 예쁜 방법 (0) | 2020.12.13 |
XAML에서 Canvas의 Children 속성을 바인딩 할 수 있습니까? (0) | 2020.12.13 |
C ++에서 int에서 상속 할 수없는 이유는 무엇입니까? (0) | 2020.12.13 |