質問: swift3でCoreDataを使っていたアプリをswift4でビルトしたら以下のCheck dependenciesがでました The use of Swift 3 @objc inference in Swift 4 mode is deprecated. Please address deprecated @objc inference warnings, test your code with “Use of deprecated Swift 3 @objc inference” logging enabled, and then disable inference by changing the "Swift 3 @objc Inference" build setting to "Default" for the "CoreDataApp" target. この警告を消したいのですが どなたか助けていただけますか。
回答: その警告はCoreDataを使っているかどうかにかかわらず、Swift 3のプロジェクトをSwift 4に移行すると必ず表示されるものです。 Xcode上で、あなたのプロジェクトのターゲットのBuild Settingsの中にSWIFT_SWIFT3_OBJC_INFERENCE と言う名前の項目がありますので探し出してください。Onになっているはずです。(Xcodeのバージョン・設定等によって違う見え方をする場合があります。) !Build Settings画面 この設定値を **Off** に書き換えて下さい。(**Default** でも同じことですが、ま、Offの方がわかりやすいでしょう。)警告メッセージの中身(の半分)は、この設定をOnにした動作はSwift 4では非推奨だから使うな、と言う意味です。この設定を書き換えることで、警告が出なくなるはずです。 ただし、アプリによっては、この設定をOffにしてしまうと実行時にクラッシュしてしまうことがあります。警告メッセージの残り半分は、そう言うことにならないように十分デバッグしてからOffにしろと書いてあるわけです。 ただ、そのために具体的に書いてある方法(なんちゃらのログ出力をオンにしろって部分)は、やり方がわかりにくい上に、私自身の経験ではあまり役に立った覚えがないので、「Offにしてから十分デバッグする」と言うのが私のおすすめです。 ### (以下は特に興味があるので突っ込んだ話を知りたいと言う場合だけ読んで下さい。) ちなみに"Swift 3 @objc inference"と言うのは、Swift言語のこの変更に関係があります。 SE-0160 Limiting @objc inference `@objc`と言うのはメソッドやプロパティ(昔はクラスも)をObjective-C互換にすることを示すアノテーションですが、ある条件の下で`@objc`を付けなくても、メソッドやプロパティが自動的にObjective-C互換になることがありました。それが「どんな条件なのかわからんし、Objective-C名(セレクタ)が被っちゃう事故がよくあるし、Swiftっぽいネーミングを自動変換すると全然Objective-Cっぽくならないことがよくあるし、なによりそのせいでコンパイルされたバイナリーがでかくなるとかのデメリットがある」ってことで、「わかりやすい特定の条件でしか、メソッドやプロパティを(指定もないのに)Objective-C互換にはしない」と言うのがSE-0160の趣旨です。 と言うわけでiOS内部やあなたのコードからセレクタ経由で呼び出される可能性のあるメソッドやプロパティなんかは、上記の設定をOffにしてしまうと、`Unrecognized selector`なんて実行時クラッシュを引き起こすエラーになる可能性があります。 `#selector`を正しく使っている場合はSwift移行ツールがいつのまにか`@objc`を追加してくれるんですが、古い書き方をしていたり、セレクタ経由であることがわかりにくい(例えばKVCやKVOに基づいたコード)場合は、移行ツールではうまく検出できないこともあります。 (CoreDataも実は、Objective-Cの実行時処理にどっぷり依存したフレームワークなんですが、そのせいで`@objc`を暗黙的に補ってくれる数少ない場合の一つになっています。) 後半少しわかりにくかったかもしれませんが、「Swift 4では、`@objc`を(明示的に)付けないと、Swift 3までなら動いていたコードが動かなくなることがある」と言うのは覚えておいていただいた方が良いでしょう。