[解決済み] Swiftの@selector()?
質問
を作成しようとしています。
NSTimer
で
Swift
が、ちょっと困っています。
NSTimer(timeInterval: 1, target: self, selector: test(), userInfo: nil, repeats: true)
test()
は同じクラスの関数です。
エディターでエラーが発生します。
init' のオーバーロードで、提供されたものを受け入れるものが見つかりませんでした。 引数
を変更すると
selector: test()
から
selector: nil
を実行すると、エラーが消えます。
試してみました。
-
selector: test()
-
selector: test
-
selector: Selector(test())
しかし、何も機能せず、参考文献にも解決策が見当たりません。
解決方法は?
スウィフト
そのもの
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
式は、実際に存在し、セレクタとして使用することができるクラスとメソッドのペアでのみ使用できます (下記の "Selector availability" を参照)。また、関数の参照は、以下のように必要なだけ具体的にすることができます。
Swift 2.2+の関数型命名のルールである
.
(これは、実際にはObjCの
@selector()
ディレクティブは、コンパイラの
-Wundeclared-selector
のチェックは、指定されたセレクタが存在するかどうかだけを確認します。に渡す Swift の関数参照は
#selector
は、存在、クラス内のメンバーシップ、およびタイプシグネチャをチェックします)。
に渡す関数参照には、さらにいくつかの注意点があります。
#selector
という式があります。
-
同じベース名を持つ複数の関数は、パラメータラベルで区別するために、前述の
関数参照用の構文
(例
insertSubview(_:at:)
対insertSubview(_:aboveSubview:)
). しかし、関数にパラメータがない場合、それを曖昧にする唯一の方法はas
を関数の型シグネチャと一緒にキャストします(例.foo as () -> ()
対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
を可視化します。
キーパスです。
これらはセレクタと関連していますが、全く同じではありません。Swift 3 では、これらのための特別な構文もあります: 例.
chris.valueForKeyPath(#keyPath(Person.friends.firstName))
. 参照
SE-0062
をご覧ください。さらにさらに
KeyPath
Swift 4 のスタッフ
そのため、適切な場合はセレクタの代わりにKeyPathベースのAPIを使用していることを確認してください。
セレクタについては、以下のページで詳しく説明しています。 Objective-CのAPIと連動する で CocoaとObjective-CでSwiftを使用する .
注
Swift 2.2以前。
Selector
に準拠しています。
StringLiteralConvertible
そのため、セレクタを受け取るAPIに裸の文字列が渡される古いコードを見つけることができるかもしれません。Xcode で "Convert to Current Swift Syntax" を実行して、以下のようなものを取得したいと思うでしょう。
#selector
.
関連
-
[解決済み】Thread 1: signal SIGABRTエラーを解決するには?[クローズド]
-
[解決済み] Swift - 呼出しの余分な引数
-
[解決済み] swiftの"? "の意味は何ですか?[重複している]。
-
[解決済み] SwiftからObjective-Cのコードを呼び出すにはどうしたらいいですか?
-
[解決済み] Swiftで#pragmaマーク?
-
[解決済み] SwiftでUIAlertViewを作成するにはどうしたらいいですか?
-
[解決済み] Swiftの精密文字列フォーマット指定子
-
[解決済み】UIViewControllerの最上位機種を取得する。
-
[解決済み] Swift言語でのエラーハンドリング
-
[解決済み] Swift で引数の数が可変の関数に配列を渡す
最新
-
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でbase64StringをStringに変換する方法とは?
-
[解決済み] メインスレッドチェッカー バックグラウンドスレッドで呼び出された UI API: -[UIApplication applicationState].
-
[解決済み] Swift 3でdispatch_onceはどうなる?
-
[解決済み] Swift 3、Swift 4、それ以降で dispatch_sync, dispatch_async, dispatch_after などはどうすればいいですか?
-
[解決済み] Swift stdlib ツール エラー
-
[解決済み] 使用しているSwiftのバージョンを確認するにはどうすればよいですか?
-
[解決済み] SwiftUIのFacebookログイン。FacebookのIDをビューに戻すには?
-
[解決済み】Swiftの構造体のために、メンバーごとの初期化子をデフォルトで公開するにはどうすればよいですか?