4
3

More than 5 years have passed since last update.

CoreDataのvalidate機能について、validate<Key>(_:)が呼び出されなくて困った件

Last updated at Posted at 2018-09-27

iOS開発初心者がCoreDataの勉強中に詰まったところを簡単ではありますが、まとめておきます。

動作環境

  • xcode9.4.1
  • Swift4.1.2

CoreDataの検証メソッドの動作について

CoreDataの検証メソッドについて、管理オブジェクトコンテキストが保存されるタイミングで、コンテキストが更新/挿入/削除が行われた管理オブジェクトを持つとき、

  • validateForUpdate()
  • validateForInsert()
  • validateForDelete()

が呼ばれます。
これらのメソッド中でvalidateValue(_:forKey:)が呼ばれ、プロパティごとの検証がされます。
validateValue(_:forKey:)の中では、キーに対して名前がvalidate<Key>(_:)のメソッドを検索し、見つかればそのメソッドを呼び出します。
これにより、エンティティの各キーに対してカスタム検証メソッドを実装できます。

発生した問題

下記のメソッドを作成しましたが、呼び出されていませんでした。
エラーメッセージが出ず、validate<Key>(_:)のメソッドが呼び出されないまま、他の処理が動いていました。

func validateTitle(_ value: AutoreleasingUnsafeMutablePointer<AnyObject?>) throws {
...

解決法

下記のように、funcの前に@objcを記述することで、メソッドが無事呼び出されました。

@objc func validateTitle(_ value: AutoreleasingUnsafeMutablePointer<AnyObject?>) throws {
...

原因の考察

Swift4以前では、暗黙的に@objcがつけられ、Objective-Cから使用できていました。
しかし、Swift4からは、明示的に@objcを用いて、Objective-Cから使用できることを宣言しなければならなくなりました。
つまり、CoreDataの内部処理をObjective-Cで行っていると推測でき、@objcの宣言が必要になっているのだと思います。

気づいた経緯

Xcodeのバージョンアップで、code Generationを指定できるようになりました。
その指定がswiftになっていたため、試しに@objcをつけてみたところ正しく動作しました。
ただし、code GenerationをObject-Cに指定して、@objcをつけないで実行しても、メソッドが呼ばれることはなかったため、code Generationは原因では無かったようです。

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3