2016-05-01 2 views
24

私はUIButtonのタップイベントにメソッドをアタッチしたいSwiftプロジェクトを持っています。私は、次のコードを持っている:Swiftは#selectorの引数がObjective-Cに公開されることを望んでいます

class MyClass { 
    let myButton = UIButton(frame: CGRectMake(50, 50, 100, 50)) 
    init() { 
    myButton.addTarget(self, #selector(self.didTap(_:)), forControlEvents: .TouchUpInside) 
    } 

    func didTap(sender: UIButton) { 
    print("Tapped") 
    } 
} 

XCodeのは、私のaddTargetラインを強調し、こう述べています。

Argument of '#selector' refers to a method that is not exposed to Objective-C 

それはすべてが正常に動作し、その後示唆のように私は私のfunc didTap@objc接頭辞を追加した場合。

この異常な動作を引き起こしているビルド設定で何かが有効になっていますか?

PS。私はこの動作を7.3.1で行っています。しかし、7.2.1でこれを試しても、#selector(method(_:))の構文は受け入れられず、Selector("method:")はうまくいきます。

答えて

58

セレクタは、Objective-Cのの特徴であるとのみ、動的オブジェクト - Cランタイムに露出されている方法で使用することができます。純粋なSwiftメソッドのセレクタを持つことはできません。

あなたのクラスには、パブリックメソッドが自動的にOBJの-Cにさらされ、その後NSObjectから継承する場合。あなたのクラスがNSObjectから継承していないので、あなたはそれがobj-Cセレクタと呼ばれることができるようにあなたは、このメソッドがobj-Cに曝露したいことを示すために@objc属性を使用する必要があります。

#selector()は、Swift 2.2の新しい構文です。コンパイラは、使用しようとしているセレクタが実際に存在するかどうかをチェックできます。古い構文は廃止され、Swift 3.0で削除されます。

+1

短くて鋭く包括的な答えです。正確に指す。 – MadNik

11

私のfunc didTapに@objcプレフィックスを追加すると、すべて正常に動作します。

この異常な動作を引き起こしているビルド設定で何かが有効になっていますか?

いいえあなたが見ているのは正常です。セレクタはObjective-Cの機能であり、セレクタを使用してクラスインスタンスにメッセージを送信します。 Objective-Cがそのメッセージを送信する唯一の方法は、クラスまたはメソッド自体を見ることができるかどうかということです。 MyClass自体はNSObjectから派生していないのでObjective-Cはそれを見ることができません。したがって、NSObjectから派生させたくない場合は、少なくとも@objcとマークすることによってObjective-Cにメソッドを公開する必要があります。

とセレクタ(「方法は:」)、コンパイラはこのような状況であなたを助けないだろうスウィフトの以前のバージョンでは

正常に動作しますので、あなたのコードがコンパイルします。しかし、メッセージが到着したときにクラッシュし、Objective-Cがそのメソッドを見つけられなかったでしょう。 #selector構文全体のポイントは、クラッシュを回避するのに役立ちます。そしてそれはそれがしたことです!

-2

サブクラスする必要がありますNSObject

関連する問題