その後のその後

iOSエンジニア 堤 修一のブログ github.com/shu223

KVC で setValue:forUndefinedKey: エラーが発生する場合の対処法

たとえば、CIFilterを使っていて、下記のようにinputImageに値(画像)を渡そうとしていて、

[filter setValue:_filteredImage forKey:@"inputImage"];

この filter が inputImage というプロパティを持たないものだったとき(たとえば CICheckerboardGenerator)に、こんなエラーが出ます。

'NSUnknownKeyException', reason: '[ setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key inputImage.'


解決法はこちらにとてもわかりやすく詳細な記事があって、以下は単なるその抜粋になります。

何が起きているのか?

  • setValue:ForKey: をあるオブジェクトへ投げたときに、当該keyが存在しない場合は setValue:forUndefinedKey: が投げられる。
  • この setValue:forUndefinedKey: はデフォルトでは例外(NSUndefinedKeyException)が発生する

解決方法

次のような解決方法が挙げられています。

  • 例外をキャッチして処理を続行 @try-@catch
  • valueForUndefinedKey: を実装(セッターの場合は setValue:forUndefinedKey:)
  • class_copyPropertyList( ) でプロパティリストを取得してチェック
  • respondsToSelector: でアクセッサ実装の有無をチェック


この中でも一番お手軽そうな、respondsToSelectorでチェック、を試してみました。

if (![filter respondsToSelector:NSSelectorFromString(@"inputImage")]) {
    return;
}
[filter setValue:_filteredImage forKey:@"inputImage"];

こんな感じで、inputImageというアクセサの有無をチェックすることで、とりあえず例外で止まることは回避できるようになりました。