병합 된 모델의 nsmanagedObjectModel의 교차 모델 관계?
-
02-07-2019 - |
문제
관련 모델을 병합하여 생성 된 nsmanagedObjectModel 내에서 엔티티가 항상 사용되는 경우 별도의 nsmanagedObjectModels에서 정의 된 엔티티 간의 관계를 모델링 할 수 있습니까?
예를 들어, 모델 1은 엔티티를 정의합니다 Foo
관계와 (일대일) toBar
그리고 그 모델 2는 엔티티를 정의합니다 Bar
관계와 함께 (일대일) toFoo
. 나는 Coredata 스택을 사용하여 만들 것이다 -[NSManagedObjectModel mergedModelFromModels]
, 모델 1 및 모델 2를 병합합니다. 데이터 모델러에서 이러한 관계를 정의 할 수있는 방법이 있습니까?
해결책
모델 1과 모델 2는 잘 형성되지 않는 한 런타임에로드 할 수 없습니다. toBar
그리고 toFoo
관계에는 목적지가 있습니다. 또한 Model 1과 Model 2가 동일하게 이름 지정된 모델을 가지고 있다면 병합 된 모델을 만들 수 없습니다. 그들은 합쳐지지 않을 것이며, 충돌 할 것입니다. 이는 오류입니다.
그러나 당신은 그것을 사용할 수 있습니다 NSManagedObjectModel
API는 수동으로 각 모델을로드하고 둘 다의 엔티티가 포함 된 새 모델을 수동으로 만듭니다. 그만큼 NSEntityDescription
그리고 NSPropertyDescription
클래스 (및 하위 클래스)는이를 구현합니다 NSCopying
프로토콜 따라서 대부분의 경우 각 구성 요소 모델에서 전체 모델로 속성을 복사 할 수 있어야합니다.
또한, NS*Description
클래스 모두 지원 a userInfo
Xcode의 데이터 모델링 도구에서 편집 할 수있는 사전은 관계의 대상을 태그와 같은 일을 할 수 있습니다. 예를 들어, 모델 1에서 Bar
a userInfo
열쇠 MyRealEntity
병합 된 모델을 만들 때 실제 엔티티를 대신 사용하는 신호로 확인하십시오.
또한 스탠드 인 엔티티에 스탠드 인트 리버스 관계를두고 싶을 것입니다. 이것들은 병합 후 실제 반전으로 대체됩니다. 그러나 모든 모델에서 스탠드 인 엔티티를 완전히 복제 할 필요는 없습니다. 실체의 스탠드에서 실제 모델에서 사용 된 역 관계 만 있으면됩니다.
따라서 당신의 진짜라면 Foo
a name
속성, 그리고 당신의 실제 막대에는 a가 있습니다 kind
속성, 당신의 스탠드 인 Foo
그리고 Bar
그냥 필요하지 않습니다 toBar
그리고 toFoo
관계.
다음은 내가 말하는 내용을 보여주는 코드입니다.
- (NSManagedObjectModel *)mergeModelsReplacingDuplicates:(NSArray *)models {
NSManagedObjectModel *mergedModel = [[[NSManagedObjectModel alloc] init] autorelease];
// General strategy: For each model, copy its non-placeholder entities
// and add them to the merged model. Placeholder entities are identified
// by a MyRealEntity key in their userInfo (which names their real entity,
// though their mere existence is sufficient for the merging).
NSMutableArray *mergedModelEntities = [NSMutableArray arrayWithCapacity:0];
for (NSManagedObjectModel *model in models) {
for (NSEntityDescription *entity in [model entities]) {
if ([[entity userInfo] objectForKey:@"MyRealEntity"] == nil) {
NSEntityDescription *newEntity = [entity copy];
[mergedModelEntities addObject:newEntity];
[newEntity release];
} else {
// Ignore placeholder.
}
}
}
[mergedModel setEntities:mergedModelEntities];
return mergedModel;
}
이것은 복사하기 때문에 작동합니다 NS*Description
핵심 데이터의 객체는 관계의 대상 엔티티와 역 (및 엔티티의 하위에도)과 관련하여 가치가 아닌 이름이 아닙니다. 따라서 모델은 변이 가능하지만, 즉, 모델로 설정되기 전에 NSPersistentStoreCoordinator
- 이와 같은 트릭을 사용하여 모델을 여러 모델로 나눌 수 있습니다.