Swift 自体はセレクターを使用しません— Objective-Cでセレクターを使用するいくつかの設計パターンは、Swiftでは動作が異なります。(たとえば、プロトコルタイプまたはis/ asテストではrespondsToSelector:、オプションのチェーンをの代わりに使用し、performSelector:タイプ/メモリの安全性を高めるために、可能な場所ではなくクロージャーを使用します。)
しかし、タイマーやターゲット/アクションパターンなど、セレクターを使用する重要なObjCベースのAPIはまだいくつかあります。SwiftはSelectorこれらを操作するためのタイプを提供します。(SwiftはこれをObjCのSEL型の代わりに自動的に使用します。)
Swift 2.2(Xcode 7.3)以降(Swift 3 / Xcode 8およびSwift 4 / Xcode 9を含む):
Selector式を使用して、Swift関数タイプからを構築でき#selectorます。
let timer = Timer(timeInterval: 1, target: object,
selector: #selector(MyClass.test),
userInfo: nil, repeats: false)
button.addTarget(object, action: #selector(MyClass.buttonTapped),
for: .touchUpInside)
view.perform(#selector(UIView.insertSubview(_:aboveSubview:)),
with: button, with: otherButton)
このアプローチの素晴らしいところは?関数参照はSwiftコンパイラーによってチェックされるため、#selector式は実際に存在し、セレクターとして使用できるクラス/メソッドのペアでのみ使用できます(以下の「セレクターの可用性」を参照)。また、関数タイプの命名に関するSwift 2.2以降のルールに従って、関数参照を必要なだけ具体的にすることもできます。
(これは実際にはObjCの@selector()ディレクティブを改良したものです。コンパイラーの-Wundeclared-selectorチェックでは、名前付きセレクターが存在することだけが検証されるためです。渡したSwift関数参照は#selector、存在、クラスのメンバーシップ、および型シグニチャーをチェックします。)
#selector式に渡す関数参照には、いくつかの追加の警告があります。
- 同じベース名を持つ複数の関数は、前述の関数参照の構文(
insertSubview(_:at:)vsなどinsertSubview(_:aboveSubview:))を使用して、パラメーターラベルで区別できます。ただし、関数にパラメーターがない場合、関数を明確にする唯一の方法はas、関数の型シグニチャー(foo as () -> ()vsなどfoo(_:))を持つキャストを使用することです。
- Swift 3.0以降では、プロパティのゲッター/セッターのペアに特別な構文があります。たとえば、を指定すると
var foo: Int、#selector(getter: MyClass.foo)またはを使用できます#selector(setter: MyClass.foo)。
一般的注意事項:
#selector機能しないケースと命名:セレクターを作成するための関数参照がない場合があります(たとえば、ObjCランタイムに動的に登録されたメソッドを使用する場合)。その場合はSelector、文字列からを作成できます。たとえばSelector("dynamicMethod:")、コンパイラの有効性チェックが失われます。その場合:、各パラメーターのコロン()を含むObjC命名規則に従う必要があります。
セレクターの可用性:セレクターによって参照されるメソッドは、ObjCランタイムに公開する必要があります。Swift 4では、ObjCに公開されるすべてのメソッドの宣言の前に@objc属性を付ける必要があります。(以前のバージョンでは、場合によってはその属性を無料で取得していましたが、現在は明示的に宣言する必要があります。)
ことを忘れないでくださいprivate、あまりにも、シンボルが実行時に公開されていません-あなたの方法は、少なくとも持っている必要がありinternal、視認性。
キーパス:これらはセレクターに関連していますが、セレクターとはまったく同じではありません。例えば:あまりにスウィフト3におけるこれらのための特別な構文が、ありますchris.valueForKeyPath(#keyPath(Person.friends.firstName))。詳細については、SE-0062を参照してください。KeyPathSwift 4にはさらに多くのものがあるため、必要に応じて、セレクターの代わりに正しいKeyPathベースのAPIを使用していることを確認してください。
セレクターの詳細については、「CocoaおよびObjective-CでのSwiftの使用」の「Objective-C APIの操作」を参照してください。
注: Swift 2.2より前はにSelector準拠しStringLiteralConvertibleていたため、セレクターを取るAPIに裸の文字列が渡される古いコードが見つかる可能性があります。Xcodeで「Convert to Current Swift Syntax」を実行して、を使用するものを取得する必要があり#selectorます。
selector: test()呼び出しtestて、その戻り値をselector引数に渡します。