[解決済み] Swift 4の#selector()で@objc推論の非推奨にどう対処すればいいですか?
質問
私は自分のプロジェクトのソースコードをSwift 3からSwift 4に変換しようとしています。Xcodeが私に与えている1つの警告は、私のセレクタについてです。
例えば、私はこのような通常のセレクタを使用して、ボタンにターゲットを追加します。
button.addTarget(self, action: #selector(self.myAction), for: .touchUpInside)
このような警告が表示されます。
selector' の引数は Swift 4 で非推奨となった '@objc' 属性推論に依存する 'ViewController' のインスタンスメソッド 'myAction()' を参照しています。
このインスタンスメソッドをObjective-Cに公開するために'@objc'を追加します。
では
Fix
を押すと、私の関数ではこのようになります。
// before
func myAction() { /* ... */ }
// after
@objc func myAction() { /* ... */ }
を含むように関数の名前をすべて変更することはあまりしたくありません。
@objc
マークを含むようにすべての関数の名前を変更したいとは思いませんし、その必要はないと思っています。
非推奨に対応するために、セレクタをどのように書き換えたらよいでしょうか。
関連する質問です。
どのように解決するのですか?
修正方法は正しいです。セレクタについて、それが参照するメソッドを Objective-C に公開するために変更できるものは何もありません。
そもそもこの警告が発生する理由は、すべて
SE-0160
. Swift 4 より前の
internal
またはそれ以上の Objective-C 互換のメンバである
NSObject
を継承するクラスは
@objc
であると推測され、したがってObjective-Cに公開されるため、セレクタを使用して呼び出すことができます(与えられたセレクタのメソッド実装を検索するためにObj-Cランタイムが必要であるため)。
しかし、Swift 4では、これはもはやそうではありません。非常に特定の宣言のみが、現在では
@objc
であると推測されます。
@objc
メソッドの実装
@objc
プロトコルの要件、およびその属性を持つ宣言を意味する
@objc
を意味する属性を持つ宣言、例えば
@IBOutlet
.
この背後にある動機は、詳細な
で、上記のリンク先の提案
におけるメソッドのオーバーロードを防ぐためです。
NSObject
を継承するクラスのメソッドのオーバーロードが、同一のセレクタを持つために互いに衝突することを防ぐためです。次に、Obj-Cに公開する必要のないメンバのサンクを生成する必要がないため、バイナリサイズを小さくすることができ、3番目にダイナミックリンクの速度を向上させることができます。
Obj-Cにメンバーを公開したい場合、そのメンバーを
@objc
といった具合です。
class ViewController: UIViewController {
@IBOutlet weak var button: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
button.addTarget(self, action: #selector(foo), for: .touchUpInside)
}
@objc func foo() {
// ...
}
}
("minimise inference" オプションを選択して実行すると、マイグレータはセレクタでこれを自動的に行うはずです)
メンバーのグループをObj-Cに公開するためには
@objc extension
:
@objc extension ViewController {
// both exposed to Obj-C
func foo() {}
func bar() {}
}
これは、その中で定義された全てのメンバーをObj-Cに公開し、Obj-Cに公開できないメンバーについては(明示的に
@nonobjc
).
が必要なクラスがある場合
全て
Obj-C互換のメンバがObj-Cに公開される必要がある場合、そのクラスを
@objcMembers
:
@objcMembers
class ViewController: UIViewController {
// ...
}
これで、推論可能なすべてのメンバが
@objc
になります。しかし、以下のような場合でなければ、この方法はお勧めできません。
本当に
はObj-Cにすべてのメンバーを公開する必要がありますが、不必要にメンバーを公開することによる上記のマイナス面を考えると、これを行うことをお勧めしません。
関連
-
[解決済み] これを解決するにはどうしたらいいのでしょうか。UILabel.textは、メインスレッドからのみ使用する必要があります。
-
[解決済み] 使用しているSwiftのバージョンを確認するにはどうすればよいですか?
-
[解決済み] プロジェクト内の単一ファイルのARCを無効にするにはどうしたらいいですか?
-
[解決済み] SwiftからObjective-Cのコードを呼び出すにはどうしたらいいですか?
-
[解決済み] Swift Betaのパフォーマンス:配列のソート
-
[解決済み] Swiftでindexとelementでループを反復させる方法
-
[解決済み] Swiftの@selector()?
-
[解決済み] 純粋な」Swift で弱いプロトコル参照を作るには (@objc なしで) どうしたらいいですか?
-
[解決済み】Swiftで変数の型またはクラスを表示するにはどうすればよいですか?
-
[解決済み】SwiftでFloatをIntに変換する。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] 型の不変値に変異型メンバを使用することはできません。
-
[解決済み] swiftにおけるconvenience initとinitの違いは何ですか、より良い明示的な例
-
[解決済み] Swiftで#pragmaマーク?
-
[解決済み] Swiftでdispatch_onceのシングルトンモデルを使う
-
[解決済み】「このアプリケーションはバックグラウンドのスレッドからオートレイアウトエンジンを変更しています」エラーが発生する?
-
[解決済み】SwiftのwillSetとdidSetの目的は何ですか?
-
[解決済み】Swiftのオプション値とは何ですか?
-
[解決済み】コンパイラーエラー。Objective-C のセレクタを持つメソッドは、同じ Objective-C セレクタを持つ以前の宣言と競合しています。
-
[解決済み】dyld: ライブラリがロードされません。rpath/libswift_stdlib_core.dylib です。
-
[解決済み] 非同期ネットワークリクエストのswift forループの実行が終了するまで待つ