핵심 데이터 기본 키


81

이것은 어리석은 것처럼 보일 수 있지만 xcdatamodel 파일에서 속성을 기본 키로 표시하는 방법을 알아낼 수 없었습니다. 내 영구 저장소는 sqlite 파일입니다. 누구든지 나를 도울 수 있습니까?

이 경우 고유 한 ID를 "확인"하려면 어떻게해야합니까? 유효성 검사 방법이나 뭔가를 작성해야합니까?

답변:


91

옵션은 다음과 같습니다.

  • 사용 -[NSManagedObject objectID]. 이 ID는 개체가 처음으로 저장되거나 다음을 호출 할 때까지 임시입니다.-[NSManagedObjectContext obtainPermanentIDsForObjects:error:]
  • CFUUID함수 패밀리를 사용 하여 -awakeFromInsert메서드의 각 개체에 대한 UUID를 생성합니다.
  • 모델에 정수를 저장하고 각 객체 생성과 함께 증분하는 고유 한 기본 키와 같은 시스템을 만듭니다.

속성이 고유한지 확인하는 좋은 방법은 없습니다. 가장 가까운 방법은 생성시 고유한지 확인한 다음 ID를 변경하는 모든 사람을 중지하는 사용자 지정 setter 메서드를 구현하는 것입니다.


5
훨씬 더 건설적인 대답-당신은 해결책으로 표시되어야합니다!
Grouchal

1
UUID를 생성하는 것이 가장 좋은 방법입니다. 우리는 앱에서 그것을 사용하고 있으며 매우 잘 제공되고 있습니다.
object2.0

46

Core Data는 데이터베이스가 아니라 객체 그래프 지속성 프레임 워크입니다. 기본 키와 같은 것은 영구 저장소의 구현에 의존하기 때문에 추상화됩니다.


2
이것은 @Mugunth가 선택해야하는 대답이어야합니다! 귀하의 통찰력에 감사드립니다.
Leonard

그렇다면 Core Data는 자체적으로 기본 키를 생성할까요?
Next Developer

24

Core Data는 자체 기본 키를 만듭니다. 추가 할 필요가 없습니다. 다음으로 검색 할 수 있습니다.

NSManagedObjectID *moID = [managedObject objectID];

14

때로 해킹 할 때 기본 키의 실제 정수가 필요합니다. 다음은 그것을 잡을 수있는 방법입니다.

NSManagedObjectID *yourManagedObjectID = [yourManagedObject objectID];
int yourManagedObject_PK = [[[[[yourManagedObjectID URIRepresentation] absoluteString] lastPathComponent] substringFromIndex:1] intValue];

CoreData가 객체 그래프 임에도 불구하고 CoreData가 생성 한 SQLite 데이터베이스 데이터를 살펴보면 NSManagedObject의 기본 키를 가져 오는이 방법은 문제가되지 않습니다. ii는 동일한 코드에서 CoreData와 저수준 sqlite3 C 라이브러리를 함께 사용했으며 레코드를 가져 오기 위해 CoreData에서 sqlite3로 기본 키를 전달하면 잘 작동합니다.

! 프로덕션에서이 코드를 사용하려는 경우 db 기본 키가 URIRepresentation으로 변환되는 방식에 대한 가능한 내부 변경 사항을 인식하면 코드가 중단 될 수 있습니다.

즐겨


1
object-ID와 SQLite RID 사이에는 관계가 정의되어 있지 않습니다. 특정 버전에 대해서만 임시 키로 사용할 수 있지만 다른 버전에서 자동으로 손상 될 수 있으므로 영구 기본 키에 대한 잘못된 접근 방식입니다 .
eonil

"다른 버전에서 깨짐"이란 정확히 무엇을 의미 했습니까? 기본 키를 변경해야하는 이유는 무엇입니까?
manitu 2014 년

PK 값은 변경되지 않지만 공식적으로 정의 된 알고리즘이 없기 때문에 URL 표현을 만드는 알고리즘이 변경 될 수 있습니다. 그리고이 경우 코드가 유효한 PK 값을 추출한다고 보장 할 수 없습니다. (알고리즘을 정의한 소스가 있으면 알려주세요. 게시를 권장합니다.)
eonil

1
확인. 해킹 부분이 납득할 때도 있습니다. 내 반대표는 현재 잠겨 있으므로 일부 편집을 수행하면 반대표를 제거하겠습니다.
eonil

2
속도와 효율성을 위해 SQL을 사용하는 경우가 있습니다. 내 예는 count (*), 합계, 평균 및 그룹을 보유하는 쿼리입니다. OO에서 할 고통, SQL에 대한 한 줄! 그 '해킹'은 완벽하게 작동하며 Apple이 변경하면 여전히 SQL 조인이 어떤 식 으로든 작동하도록 만들어야하므로 잠시 동안 괜찮다고 생각합니다.). 이론적으로 우리가 이것을하지 말아야 할지라도 투표하십시오. 제 생각에 DB를 완전히 숨기는 것은 실제 기술적 이유보다 원칙에 의해 더 많이 발생하는 오류입니다. 우리는 SQL로 배치를 얻습니다. 프레임 워크를 사용할 수 있더라도 다른 많은 시스템에서 항상.
Eric Giguere 2014 년


0

기본 키를 검색하는 Swift Extension

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)...])
     }
}

-3

차라리 시간 + 클래스 이름을 고유 식별자로 사용하고 싶습니다.


2
실제로 권장되지 않습니다. 한 번에 두 개 이상의 객체가 생성되지 않도록 보장 할 수있는 경우는 언제입니까?
fat32

너무 권장하지 않습니다. 이 방법은 키가 고유하다는 것을 보장 할 수 없습니다.
코디

@Fynh 내가 코드를 게시했는데 내 게시물이 불완전 할 수 있지만 항상 시간 게터 방법을 동기화하고 있습니다.
infiniteLoop
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.