【Swift】Core Dataの設定。リレーションシップの削除ルールや参照タイプを設定する(Swift 2.1、XCode 7.2)

2020年6月16日

Relationshipの設定

本記事ではRelationship(以下、リレーションシップ)のデータモデルインスペクタの設定項目について説明する。

リレーションシップの使い方については前回記事を参照されたし。⇒「前回記事

Core Dataのデータモデルインスペクタの設定

 

設定画面を開くには下図赤枠の「プロジェクト名.xcdatamodeld」を選択、黄緑枠のエンティティを選択、黄枠のリレーションシップを選択、紫枠のデータモデルインスペクタボタンを押す。

CoreDataのRelationshipのデータモデルインスペクタを開く

 

Name

リレーションシップの名前を設定する。

左側のリレーションシップ一覧の項目「Relatiohship」と同じ値になる。紛らわしいので左側の項目名はNameにした方がいいような気がする。

リレーションシップ一覧のRelattionshipとデータモデルインスペクタのNameは同じ値

 

Transient

チェックを入れると外部ファイルに保存されない一時的なリレーションシップになる。考え方はAttributeのTransientと同じなので、詳細は次の記事を参照されたし。⇒「Attributeの記事

 

Optional

必須項目、任意項目のどちらにするかの設定。チェックを入れると任意項目になり、値を設定しなくてもエラーは発生しない。デフォルトはチェックが入っている。

 

Destination

参照先のエンティティを指定する。例えば、下図の生徒エンティティの参照先は部活エンティティになる。

リレーションシップの例

 

Inverse

反対方向のリレーションシップを指定する。例えば上図の「生徒から部活へのリレーション」の反対方向のリレーションは「部活から生徒へのリレーション」になる。

これを設定しておけば一方のリレーションを更新したときに、反対方向のリレーションも自動で更新してくれる。

Delete Rule

オブジェクトを削除するときのルールを「No Action」、「Nullify」、「Cascade」、「Deny」から選択する。不要なデータを残したり、データの不整合を発生させないためにも、この設定はよく考えて設定する必要がある。

1つずつ確認しよう。

 

No Action

オブジェクトを消しても参照先のオブジェクトには何も起きない。なので逆方向のリレーションシップに存在しない参照先が残り続ける。

例えば、下図の中西さんを削除したとき、逆方向のリレーションシップで中西さんを参照している野球部は、中西さん削除後も中西さんの参照先を持ち続ける。

そのため、野球部のリレーションシップを利用するときに、存在しないオブジェクトを参照しようとする。

No Action

 

Nullify

オブジェクトを消したときに参照先のオブジェクトの逆方向のリレーションシップをnilにする。

例えば、下図の中西さんを削除したとき、逆方向のリレーションシップで中西さんを参照している野球部は、中西さん削除とともに中西さんを参照先しなくなる。よって、データの整合性は保たれる。

Delete Ruleに「Nullify」を設定する

 

Cascade

オブジェクトを消したときに参照先のオブジェクトも一緒に削除される。

例えば、下図の中西さんを削除したとき、参照先の野球部も一緒に削除される。そのため、佐藤さんのリレーションシップを利用するときに、存在しない野球部のオブジェクトを参照しようとする。

Delete Ruleに「Cascade」を設定

 

Deny

他のオブジェクトを参照している状況でオブジェクトを削除しようとするエラーが発生する。

Error Domain=NSCocoaErrorDomain Code=1600 “The operation couldn’t be completed. (Cocoa error 1600.)" UserInfo={NSValidationErrorObject

 

例えば、下図の中西さんを削除しようとしても中西さんは野球部を参照しているため削除することはできない。

Delete Ruleに「Deny」を設定

 

では、生徒から野球部へのリレーションシップのDelete Ruleは4つの選択肢のうちどれが適しているかを考えてみる。

  • 生徒オブジェクトは追加、削除されることがある。
  • 部活に所属している生徒は一人とは限らないので、生徒オブジェクトを削除したときに野球部オブジェクトは残す必要がある。
  • 生徒オブジェクトを削除したときに、野球部オブジェクトから生徒オブジェクトへの参照も削除する必要がある。

上記を考慮すると、「Nullify」が適しているという結論になる。

 

Type

参照先のオブジェクトの数を「To One(1つ)」と「To Many(複数)」から選択する。

例えば下図の場合、生徒オブジェクトが参照する部活オブジェクトの数は1つなので「To One」を設定する。一方、部活オブジェクトが参照する生徒オブジェクトの数は複数あるので逆方向のリレーションシップには「To Many」を設定する。

生徒と部活の例

 

「To One」を設定してエンティティのサブクラスを作ると、以下コードの「所属部」のように、参照先のクラスを型とするプロパティが生成される。オブジェクトは1つのオブジェクトを参照するということだ。

 

「To Many」を設定してエンティティのサブクラスを作ると、以下のコードの「部員」のように、NSSet型のプロパティが生成される。オブジェクトは複数のオブジェクトを参照するということだ。

 

「To Many」に設定すると下図赤枠の設定項目が追加される。

Typeを「To Many」に設定したときに表示される設定項目

 

Arrangement

先ほどはNSSet型のプロパティが生成されたが、Orderedにチェックを入れてエンティティのサブクラスを作るとNSOrderSet型のプロパティが生成される。

NSOrderSetは順序付けらて重複を許さないセットなので、管理オブジェクトコンテキストに格納した順番にデータを取り出すことができるようになる。

 

Count

参照先オブジェクトの個数の最小値と最大値を設定する。条件を満たさない状況でsaveメソッドを呼び出すとエラーが発生する。

Error Domain=NSCocoaErrorDomain Code=1580 “The operation couldn’t be completed. (Cocoa error 1580.)" UserInfo={NSValidationErrorObject=<