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は原因では無かったようです。