修正は正しい–セレクターが参照するメソッドをObjective-Cに公開するために変更できるセレクターについては何もありません。
この警告の最初の理由は、SE-0160の結果です。Swift 4以前internal
は、NSObject
継承クラスのObjective-C互換メンバーは、@objc
とれ、Objective-Cに公開されていたため、セレクターを使用してそれらを呼び出すことができました(メソッドを検索するためにObj-Cランタイムが必要になるため)特定のセレクターの実装)。
ただし、Swift 4では、これは当てはまりません。非常に具体的な宣言のみが@objc
、たとえば、@objc
メソッドの、@objc
プロトコル要件の実装@objc
、などの暗黙の属性を持つ宣言など、ようになりました@IBOutlet
。
詳細は、この背後にある動機、 上記のリンクされた提案でれているように、は、最初にメソッドのオーバーロードを防ぐNSObject
継承するクラスのが同一のセレクターがあるために互いに衝突するのことです。2つ目は、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() {
// ...
}
}
(「最小化推論」オプションを選択して実行すると、マイグレーターはセレクターを使用してこれを自動的に行います)
メンバーのグループを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に曝露され、すべてのメンバーが必要不必要にさらさ有する部材の上記の欠点を考えると、。
@objc
であるのObj-Cにそれらを公開するので、セレクタで使用するために、今必要。