핵심 데이터 모델과 관리되는 개체 간의 차이점 이해

에 의해 게시 도니 월스 10 월 5, 2020

당신은 엑스 코드가 핵심 데이터 모델 파일을 기반으로 당신의NSManagedObject클래스를 생성 할 때,관리되는 개체의 속성의 대부분은 선택 사항임을 알 수 있습니다. 당신이 그들을 모델 편집기에서 필요한 만든 경우에도,엑스 코드는 대부분의 속성이 선택 사항입니다 관리 개체를 생성합니다.

이 글에서 우리는이 현상을 탐구 할 것이다,그리고 왜 그런 일이.핵심 데이터 모델에 엑스 코드의 자동 코드 생성을 사용하는 프로젝트를 빌드할 때 프로젝트를 빌드할 때NSManagedObject하위 클래스가 생성됩니다. 이러한 클래스는 프로젝트의 파생 데이터 폴더에 작성되므로 직접 수정해서는 안됩니다. 모델 편집기에서 속성을 선택 사항으로 만들었는지 여부에 관계없이 엔터티에 추가한 일부 속성에 대한 선택적 속성이 있습니다.

처음에는 이상하게 들릴 수도 있지만 실제로는 그렇게 이상하지 않습니다. 다음NSManagedObject하위 클래스를 살펴보십시오:

extension ToDoItem { @nonobjc public class func fetchRequest() -> NSFetchRequest<ToDoItem> { return NSFetchRequest<ToDoItem>(entityName: "ToDoItem") } @NSManaged public var completed: Bool @NSManaged public var label: String?}

ToDoItem에 대한 두 가지 속성 중 하나는 모델 편집기에서 모두 필요한 경우에도 선택 사항입니다. 이ToDoItem의 인스턴스를 만들 때 다음 코드를 사용합니다:

let item = ToDoItem(context: managedObjectContext)

관리되는 개체의 이니셜라이저는 관리되는 개체 컨텍스트를 사용합니다. 즉,ToDoItem을 초기화하는 동안 관리 속성에 값을 할당하지 않습니다. labelcompleted속성 모두에 대한 값을 인쇄하면 흥미로운 결과가 나타납니다:

print(item.label) // nilprint(item.completed) // false

label이 예상대로nil인 반면 핵심 데이터는completed속성에 기본값false을 할당했습니다. 한 단계 더 나아가 다음 코드를 살펴보겠습니다:

let item = ToDoItem(context: managedObjectContext)item.label = "Hello, item"print(item.label) // "Hello, item"print(item.completed) // falsedo { try managedObjectContext.save()} catch { print(error)}

이 코드를 실행하면 다음과 같은 출력이 생성됩니다:

Optional("Hello, item")falseError Domain=NSCocoaErrorDomain Code=1570 "completed is a required value." UserInfo={NSValidationErrorObject=<CoreDataExample.ToDoItem: 0x60000131c910> (entity: ToDoItem; id: 0x600003079900 <x-coredata:///ToDoItem/t1FABF4F1-0EF4-4CE8-863C-A815AA5C42FF2>; data: { completed = nil; label = "Hello, item";}), NSValidationErrorKey=completed, NSLocalizedDescription=completed is a required value.}

이 오류는completed가 설정되지 않았 음을 의미하는completed is a required value.라고 명확하게 말하고 오류 메시지와 함께 표시된 인쇄 된 관리 객체는completednil임을 보여줍니다. 따라서completed에 어떤 종류의 기본값이 있지만 명시 적으로 할당 될 때까지nil가 아닌 것으로 간주되지 않습니다.

무슨 일이 일어나고 있는지 이해하기 위해completed에 값을 할당하고item에 대한 인쇄 된 설명을 다시 살펴볼 수 있습니다:

let item = ToDoItem(context: managedObjectContext)item.label = "Hello, item"print(item.completed)print(item)

이 코드는 다음과 같은 출력을 생성합니다:

false<CoreDataExample.ToDoItem: 0x6000038749b0> (entity: ToDoItem; id: 0x600001b576e0 <x-coredata:///ToDoItem/tD27C9C9D-A676-4280-9D7C-A1E154B2AD752>; data: { completed = 0; label = "Hello, item";})

이것은 꽤 흥미 롭지 않습니까?

completed속성은Bool로 정의되지만 숫자로 인쇄됩니다. 우리는 기본 스퀘어 라이트 저장소에서이 이유를 찾을 수 있습니다. 데이터 저장소의 핵심 파일을 탐색하는 가장 쉬운 방법은-com.apple.CoreData.SQLDebug 1을 앱에 대한 시작 인수로 전달하고 핵심 데이터가 연결된 파일을 열어서 데이터베이스 브라우저와 같은 핵심 데이터 탐색기에서 여는 것입니다.

팁:
이 게시물의 핵심 데이터 시작 인수에 대해 자세히 알아보십시오.

ZTODOITEM의 스키마 정의를 보면ZCOMPLETED의 유형으로INTEGER를 사용한다는 것을 알 수 있습니다. 즉,completed속성이 기본 저장소에 정수로 저장됩니다. completedINTEGER으로 저장되는 이유는 간단합니다. 0 은false을 나타내고 1 은true를 나타냅니다.

관리되는 개체 인스턴스를 인쇄할 때 인쇄되는datacompleted속성의 값이 아닙니다.

이 섹션에서 배울 수있는 두 가지가있다.

먼저 정의된 핵심 데이터 모델의 선택성과 생성된 관리되는 개체 간에 불일치가 있음을 알 수 있습니다. 선택적이지 않은String는 생성된 모델에서 선택적이지 않은String로 표시되고,선택적이지 않은Bool는 생성된 모델에서 선택적이지 않은Bool로 표시됩니다.두 번째로,관리 대상 개체 모델에서 값이 표현되는 방식과 기본 저장소에서 값이 표현되는 방식이 다르다는 것을 알게 되었습니다. 관리되는 개체 인스턴스를 기본 저장소에 쓰는 데 사용되는 값을 확인하려면 관리되는 개체를 인쇄하고 인쇄된 출력에서data필드를 읽을 수 있습니다.

여기서 중요한 교훈은 모델 편집기의 핵심 데이터 모델과 관리되는 객체 하위 클래스가 데이터를 같은 방식으로 나타내지 않는다는 것입니다. 핵심 데이터 모델의 선택 사항이 관리되는 객체 하위 클래스에서 항상 선택 사항을 의미하는 것은 아니며 그 반대의 경우도 마찬가지입니다. 핵심 데이터 모델의 비 선택적 값은 관리되는 개체 하위 클래스의 선택적 값으로 표현 될 수 있습니다. 핵심 데이터는 영구 저장소에 쓰려고 할 때 관리되는 개체 모델에 대해 관리되는 개체의 유효성을 검사하고 유효성 검사 오류가 발생하면 오류를 발생시킵니다.

왜이 불일치가 존재합니까? 관리되는 개체 모델 및 관리되는 개체 하위 클래스에 직접 매핑이 있으면 훨씬 쉽지 않을까요?

관리되는 개체와 핵심 데이터 모델 간의 불일치 이해

관리되는 개체와 모델 편집기에서 정의한 모델 간에 불일치가 있는 이유는 핵심 데이터의 목표-씨 루트에서 비롯됩니다.

Optional을 다루지 않기 때문에 모델 정의에서 스위프트 코드로의 좋은 매핑이 항상있는 것은 아닙니다. 때때로,매핑이 작동하는 방식은 다소 임의적 인 것 같다. 예를 들어Optional<String>Optional<Bool>은 모두OptionalNSString에 존재하지 않는다는 단순한 이유 때문에Optional이 객관적인 유형으로 표현 될 수 없습니다. 불행히도Optional<Bool>은 목표에서 아무 것도 매핑 할 수 없습니다.@NSManaged속성을Bool?로 정의하려고 할 때 엑스 코드가 자동으로 알려줍니다.

객관적으로 일한 적이 없다면Optional이라는 개념이 없다는 것이 매우 이상하게 보일 수 있습니다. 사람들은 스위프트 전에 핵심 데이터에 선택적 속성을 어떻게 사용 했습니까? 그리고 어떤 것이 목표에서nil로 가정 될 때 어떤 일이 발생합니까?

목표-다 당신이 그것을 기대하지 않더라도 어떤 값이nil가되는 것은 완벽하게 괜찮습니다. 그리고 핵심 데이터는 객관적인 뿌리를 가지고 있기 때문에 이 레거시 중 일부는 생성 된 스위프트 클래스에 이상적인 방식으로 전달되기도합니다.

여기서 가장 중요한 테이크 아웃은 객관적 작동 방식이나 엑스 코드가 정확히 코드를 생성하는 방식이 아닙니다. 대신 핵심 데이터 모델 정의의 유형 및 구성이(생성 된)관리 객체 하위 클래스의 유형과 일치 할 필요가 없다는 것을 기억하십시오.

요약

이번 주 기사에서는 관리되는 개체 하위 클래스와 핵심 데이터 모델 정의가 항상 예상대로 정렬되지 않는 방법에 대해 많은 것을 배웠습니다. 모델 편집기에서 선택 사항이 아닌 속성이 생성된 관리되는 개체 하위 클래스에서 선택 사항으로 끝날 수도 있고,기본값을 직접 할당하지 않은 경우에도 기본값이 있는 선택 사항이 아닌 속성으로 끝날 수도 있습니다.

또한 관리되는 개체 인스턴스에 기본값이 있으면 핵심 데이터 모델 편집기에서 기본값을 명시적으로 정의하지 않는 한 관리되는 개체를 저장할 때 값이 실제로 존재한다는 의미는 아닙니다.

이것은 확실히 혼란스럽고 불행한 일이지만 핵심 데이터는 관리되는 객체를 저장하는 동안 발생하는 오류에서 무엇이 잘못되었는지 알려주는 데 꽤 능숙합니다. 또한 관리되는 개체 인스턴스를 인쇄하고data속성을 검사하여 핵심 데이터가 저장하려고 시도하는 값을 검사할 수도 있습니다.

개인 메모에서 나는 이번 주 문서에서 설명한 동작은 관리 대상 서브 클래스가 가까이,모델 편집기에 정의 된 핵심 데이터 모델에 직접 매핑이있는 경우보다 신속한 친화적 만드는 핵심 데이터에 대한 향후 업데이트에서 해결되기를 바랍니다. 그러나 그때까지는 모델 편집기와 관리되는 개체 하위 클래스가 동일한 방식으로 모델을 나타내지 않으며,이는 핵심 데이터의 목표 루트와 적어도 부분적으로 관련되어 있음을 이해하는 것이 중요합니다.

이 게시물에 대한 질문,수정 또는 의견이 있으면 트위터에 알려 주시기 바랍니다. 이 게시물은 연구의 일부의 일부입니다,내가 작업하고있어 핵심 데이터에 대한 책을하고 있어요 탐사 및 준비. 이 책에 대한 업데이트는 트위터에 나를 따라해야합니다. 나는 현재 2020 년 말에 책을 발표 할 계획이다.

나의 주간 회보에 최신 체재

실용 결합

당신이 결합에 대해 알아야 할 모든 것을 배우고 어떻게 내 새 책 실용 결합과 프로젝트에서 사용할 수 있습니다. 당신은 열세 장,놀이터 및 샘플 프로젝트의 소수를 얻을 당신이 얻을 가능한 한 빨리 결합으로 실행하는 데 도움이됩니다.

이 책은 단지$29.99 에 대한 디지털 다운로드로 사용할 수 있습니다!

실제 결합 얻기

답글 남기기

이메일 주소는 공개되지 않습니다.