모든 핵심 데이터 관계에 역수가 있어야합니까?
의 내가 두 엔티티 클래스가 있다고 가정 해 봅시다 : 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는 데이터 무결성을 보장합니다. 성능 문제가 발생하면 나중에 반비례 관계를 쉽게 제거 할 수 있습니다.
The better question is, "is there a reason not to have an inverse"? Core Data is really an object graph management framework, not a persistence framework. In other words, its job is to manage the relationships between objects in the object graph. Inverse relationships make this much easier. For that reason, Core Data expects inverse relationships and is written for that use case. Without them, you will have to manage the object graph consistency yourself. In particular, to-many relationships without an inverse relationship are very likely to be corrupted by Core Data unless you work very hard to keep things working. The cost in terms of disk size for the inverse relationships really is insignificant in comparison to the benefit it gains you.
There is at least one scenario where a good case can be made for a core data relationship without an inverse: when there is another core data relationship between the two objects already, which will handle maintaining the object graph.
For instance, a book contains many pages, while a page is in one book. This is a two-way many-to-one relationship. Deleting a page just nullifies the relationship, whereas deleting a book will also delete the page.
However, you may also wish to track the current page being read for each book. This could be done with a "currentPage" property on Page, but then you need other logic to ensure that only one page in the book is marked as the current page at any time. Instead, making a currentPage relationship from Book to a single page will ensure that there will always only be one current page marked, and furthermore that this page can be accessed easily with a reference to the book with simply book.currentPage.
What would the reciprocal relationship be in this case? Something largely nonsensical. "myBook" or similar could be added back in the other direction, but it contains only the information already contained in the "book" relationship for the page, and so creates its own risks. Perhaps in the future, the way you are using one of these relationships is changed, resulting in changes in your core data configuration. If page.myBook has been used in some places where page.book should have been used in the code, there could be problems. Another way to proactively avoid this would also be to not expose myBook in the NSManagedObject subclass that is used to access page. However, it can be argued that it is simpler to not model the inverse in the first place.
In the example outlined, the delete rule for the currentPage relationship should be set to "No Action" or "Cascade", since there is no reciprocal relationship to "Nullify". (Cascade implies you are ripping every page out of the book as you read it, but that might be true if you're particularly cold and need fuel.)
When it can be demonstrated that object graph integrity is not at risk, as in this example, and code complexity and maintainability is improved, it can be argued that a relationship without an inverse may be the correct decision.
While the docs don't seem to require an inverse, I just resolved a scenario that did in fact result in "data loss" by not having an inverse. I have a report object that has a to-many relationship on reportable objects. Without the inverse relationship, any changes to the to-many relationship were lost upon relaunch. After inspecting the Core Data debug it was apparent that even though I was saving the report object, the updates to the object graph (relationships) were never being made. I added an inverse, even though I don't use it, and voila, it works. So it might not say it's required but relationships without inverses can definitely have strange side effects.
Inverses are also used for Object Integrity
(for other reasons, see the other answers):
권장되는 방법은 양방향 관계를 모델링하고 역관계를 적절하게 지정하는 것입니다. Core Data는이 정보를 사용하여 변경시 객체 그래프의 일관성을 보장합니다.
제공된 링크는 왜 inverse
세트 가 필요한지에 대한 아이디어를 제공합니다 . 그것 없이는 데이터 / 무결성을 잃을 수 있습니다. 또한 nil
더 가능성이 높은 개체에 액세스 할 가능성이 있습니다.
참고 URL : https://stackoverflow.com/questions/764125/does-every-core-data-relationship-have-to-have-an-inverse
'Programming' 카테고리의 다른 글
Django 템플릿에 현재 연도를 표시하는 방법은 무엇입니까? (0) | 2020.06.13 |
---|---|
MySQL-WHERE 절에서 COUNT (*) 사용 (0) | 2020.06.13 |
VIM ctrlp.vim 플러그인 : 파일을 다시 스캔하는 방법? (0) | 2020.06.13 |
TypeScript : 빈 타입의 컨테이너 배열 만들기 (0) | 2020.06.13 |
Rails에서 브라우저 페이지 캐싱을 방지하는 방법 (0) | 2020.06.13 |