의 내가 두 엔티티 클래스가 있다고 가정 해 봅시다 : SocialApp
및SocialAppType
에서 SocialApp
: 나는 하나 개의 속성이 appURL
하나 개의 관계 : type
.
에서 SocialAppType
나는 세 가지 속성이 있습니다 baseURL
, name
하고 favicon
.
SocialApp
관계 의 대상 type
은의 단일 레코드입니다 SocialAppType
.
예를 들어, 여러 Flickr 계정의 경우 여러 SocialApp
레코드가 있으며 각 레코드에는 개인의 계정에 대한 링크가 있습니다. SocialAppType
“Flickr”유형에는 모든 SocialApp
레코드가 가리키는 하나의 레코드 가 있습니다 .
나는이 스키마를 사용하여 응용 프로그램을 빌드 할 때 사이에 반비례 관계가 없다는 것을, 내가 경고를 SocialAppType
하고 SocialApp
.
/Users/username/Developer/objc/TestApp/TestApp.xcdatamodel:SocialApp.type: warning: SocialApp.type -- relationship does not have an inverse
역수가 필요한 이유는 무엇입니까?
답변
실제로, 나는 적어도 내가 알고있는 역수가 없기 때문에 데이터 손실이 없었습니다. 빠른 Google은 다음을 사용해야한다고 제안합니다.
역의 관계는 일을 더 깔끔하게 만드는 것이 아니라 실제로 데이터 무결성을 유지하기 위해 Core Data에서 사용됩니다.
일반적으로 관계를 양방향으로 모델링하고 역관계를 적절하게 지정해야합니다. Core Data는이 정보를 사용하여 변경시 객체 그래프의 일관성을 유지합니다 (“관계 및 객체 그래프 무결성 조작”참조). 양방향으로 관계를 모델링하지 않을 수있는 몇 가지 이유와 그렇지 않은 경우 발생할 수있는 일부 문제에 대한 내용은“단방향 관계”를 참조하십시오.
답변
Apple 설명서에는 역의 관계가 없어서 문제가 발생할 수있는 상황을 나타내는 훌륭한 예가 있습니다. 이 경우에 매핑합시다.
다음과 같이 모델링했다고 가정하십시오.
당신은이 주 에 – 하나 “라는 관계 유형 에서,” SocialApp
로 SocialAppType
. 관계는 선택 사항 이 아니며 “거부”삭제 규칙이 있습니다.
이제 다음을 고려하십시오.
SocialApp *socialApp;
SocialAppType *appType;
// assume entity instances correctly instantiated
[socialApp setSocialAppType:appType];
[managedObjectContext deleteObject:appType];
BOOL saved = [managedObjectContext save:&error];
관계가 선택 사항이 아닌 반면 삭제 규칙을 거부로 설정했기 때문에이 컨텍스트 저장에 실패합니다.
그러나 여기서 절약은 성공합니다.
그 이유는 우리가 반비례 관계를 설정하지 않았기 때문입니다 . 따라서 appType이 삭제 될 때 socialApp 인스턴스가 변경된 것으로 표시되지 않습니다. 따라서 저장하기 전에 socialApp에 대한 유효성 검증이 수행되지 않습니다 (변경이 발생하지 않았으므로 유효성 검증이 필요하지 않은 것으로 가정 함). 그러나 실제로 변화가 일어났습니다. 그러나 반영되지 않습니다.
우리가 appType을 리콜하면
SocialAppType *appType = [socialApp socialAppType];
appType은 nil입니다.
이상하지 않습니까? 선택 사항이 아닌 속성에 대해서는 0을 얻습니까?
따라서 당신은 역관계를 설정해도 아무런 문제가 없습니다. 그렇지 않으면 다음과 같이 코드를 작성하여 강제 유효성 검사를 수행해야합니다.
SocialApp *socialApp;
SocialAppType *appType;
// assume entity instances correctly instantiated
[socialApp setSocialAppType:appType];
[managedObjectContext deleteObject:appType];
[socialApp setValue:nil forKey:@"socialAppType"]
BOOL saved = [managedObjectContext save:&error];
답변
필자는 Dave Mark와 Jeff LeMarche의 More iPhone 3 Development 에서 찾은 확실한 답을 역설 할 것입니다.
Apple은 일반적으로 앱에서 역 관계를 사용하지 않더라도 항상 역을 만들고 지정하는 것이 좋습니다. 이러한 이유로 역을 제공하지 않으면 경고합니다.
역 관계가 성능을 손상시킬 수있는 몇 가지 시나리오가 있기 때문에 관계에 역이 필요 하지 않습니다 . 예를 들어, 역의 관계에 매우 많은 수의 객체가 포함되어 있다고 가정합니다. 역수를 제거하려면 역 약화 성능을 나타내는 집합을 반복해야합니다.
그러나 특별한 이유가 없다면 inverse를 모델링하십시오 . Core Data는 데이터 무결성을 보장합니다. 성능 문제가 발생하면 나중에 반비례 관계를 쉽게 제거 할 수 있습니다.
답변
더 좋은 질문은 ” 반대 하지 않는 이유 가 있습니까?”입니다. 핵심 데이터는 실제로 지속성 프레임 워크가 아닌 객체 그래프 관리 프레임 워크입니다. 즉, 그 역할은 객체 그래프에서 객체 간의 관계를 관리하는 것입니다. 역관계는 훨씬 쉬워집니다. 이러한 이유로 Core Data는 역의 관계를 기대하며 해당 사용 사례를 위해 작성되었습니다. 그것들이 없으면 객체 그래프 일관성을 직접 관리해야합니다. 당신이 작동하지 않는 특히, 역 관계없이 일대 다 관계는 매우 가능성이 코어 데이터가 손상 될 수 있습니다 매우 작업하게 유지하기 어렵다. 역 관계에 대한 디스크 크기 측면에서 비용은 실제로 얻는 이점과 비교하여 중요하지 않습니다.
답변
역전없이 핵심 데이터 관계에 대해 좋은 사례를 만들 수있는 시나리오가 적어도 하나 있습니다. 두 객체 사이에 다른 핵심 데이터 관계가 이미있는 경우 객체 그래프 유지 관리를 처리합니다.
예를 들어, 책에 여러 페이지가 포함되어 있고 한 페이지에 페이지가 있습니다. 이것은 양방향 다 대일 관계입니다. 페이지를 삭제하면 관계가 무효가되고 책을 삭제하면 페이지도 삭제됩니다.
그러나 각 책에 대해 현재 읽고있는 페이지를 추적 할 수도 있습니다. 이것은 “currentPage”와 함께 할 수있는 재산 에 페이지 ,하지만 당신은 책의 한 페이지가 언제든지 현재의 페이지로 표시되어 있는지 확인하기 위해 다른 논리가 필요합니다. 대신, Book에서 단일 페이지로 currentPage 관계 를 설정하면 항상 하나의 현재 페이지 만 표시되며, book.currentPage를 사용하여 책을 참조하여이 페이지에 쉽게 액세스 할 수 있습니다.
이 경우 상호 관계는 무엇입니까? 무의미한 것. “myBook”또는 이와 유사한 항목을 다른 방향으로 다시 추가 할 수 있지만 페이지에 대한 “book”관계에 이미 포함 된 정보 만 포함되므로 자체 위험이 발생합니다. 아마도 미래에는 이러한 관계 중 하나를 사용하는 방식이 변경되어 핵심 데이터 구성이 변경 될 수 있습니다. 코드에서 page.book을 사용해야하는 곳에서 page.myBook을 사용한 경우 문제가있을 수 있습니다. 이를 사전에 피하는 또 다른 방법은 페이지에 액세스하는 데 사용되는 NSManagedObject 서브 클래스에 myBook을 노출시키지 않는 것입니다. 그러나 처음에는 역을 모델링하지 않는 것이 더 간단하다고 주장 할 수 있습니다.
설명 된 예에서 currentPage 관계에 대한 삭제 규칙은 “Nullify”에 대한 상호 관계가 없으므로 “No Action”또는 “Cascade”로 설정해야합니다. (캐스케이드는 책을 읽을 때 모든 페이지를 책에서 추출한다는 것을 의미하지만, 특히 차가워서 연료가 필요한 경우에 해당 될 수 있습니다.)
이 예에서와 같이 객체 그래프 무결성이 위험하지 않다는 것이 입증 될 수 있고 코드 복잡성 및 유지 관리 성이 개선되면, 역의 관계가없는 관계가 올바른 결정일 수 있다고 주장 할 수 있습니다.
답변
문서에는 역수가 필요하지 않은 것처럼 보이지만 실제로는 역이 없어서 “데이터 손실”이 발생하는 시나리오를 해결했습니다. 보고 가능한 개체와 많은 관계가있는 보고서 개체가 있습니다. 반비례 관계가 없으면 다 대다 관계에 대한 변경 사항이 다시 시작될 때 손실되었습니다. 핵심 데이터 디버그를 검사 한 후 보고서 개체를 저장하더라도 개체 그래프 (관계)에 대한 업데이트가 수행되지 않았 음을 알 수있었습니다. 나는 그것을 사용하지 않더라도 역을 추가했으며, voila는 작동합니다. 따라서 그것이 필요하다고 말할 수는 없지만 역수가없는 관계는 분명히 이상한 부작용을 가질 수 있습니다.
답변
역수도 사용됩니다 Object Integrity
(다른 이유로 다른 답변 참조).
권장되는 방법은 양방향 관계를 모델링하고 역관계를 적절하게 지정하는 것입니다. Core Data는이 정보를 사용하여 변경시 객체 그래프의 일관성을 보장합니다.
제공된 링크는 왜 inverse
세트 가 필요한지에 대한 아이디어를 제공합니다 . 그것 없이는 데이터 / 무결성을 잃을 수 있습니다. 또한 nil
더 가능성이 높은 개체에 액세스 할 가능성이 있습니다.