배경
- 임성수님의 코어데이터 강의를 들으면서 delete rule에 관해 더 깊이 이해할 수 있는 기회가 생겼다.
NSDeleteRule
- Relation 삭제 시 발생하는 작업을 정의하는 delete rule은 NSDeleteRule 이라는 열거형으로 정의되어있다.
- 각각의 규칙을 살펴보자.
noActionDeleteRule
- 참조된 managed object의 수정을 방지하는 규칙
- 이 규칙을 사용하면 참조된 managed object를 삭제하거나 해당 객체의 역관계를 무효화(nullify)해야 한다.
- 그렇지 않으면 해당 객체들은 더 이상 존재하지 않는 객체를 참조하게 되고, 영구 저장소는 일관성을 잃게 된다.
nullifyDeleteRule
- 참조된 managed object의 역관계를 무효화(nullify)하는 규칙
cascadeDeleteRule
- 참조된 managed object를 삭제하는 규칙
denyDeleteRule
- Relationship이 다른 객체에 대한 참조를 가지고 있다면 owning managed object 삭제를 방지하는 규칙
내가 헷갈렸던 지점
- 공유 킥보드 앱에서, 킥보드와 킥보드 타입 간의 관계에서 삭제 규칙을 설정해야 했다.
- 이 때 킥보드를 삭제해도 킥보드 타입은 삭제되면 안 된다고 생각해, 삭제 규칙은 noAction을 선택해야 한다고 생각했었다.
- 그러나 코어 데이터는 데이터베이스가 아니라 프레임워크이고, 엔티티와 어트리뷰트는 객체 그래프라는 사실을 간과하고 있었다.
- 따라서 서로 관계를 맺는다는 것은 각 객체간 참조가 발생한다는 의미라고 생각해야 한다.
- 킥보드 <-> 킥보드 타입은 서로 참조를 갖고 있기 때문에, 킥보드 삭제 시 noAction을 선택하면 킥보드 객체만 사라지고 킥보드 타입이 킥보드를 바라보는 참조는 남아있다.
- 따라서 오류가 발생할 수 있고, 저장소 일관성이 없어진다는 문제가 발생한다.
- 이렇듯 해당 객체에 대한 참조가 있는 릴레이션(역관계)이 있을 경우엔 noAction이 아닌 nullify를 선택해 역관계를 무효화해야 한다~!
참고
https://joonswift.tistory.com/47
https://developer.apple.com/documentation/coredata/nsdeleterule/denydeleterule