2016-04-25 5 views
6

今まで、私は、私はこのコードを書いていない、このコードSwift 3セレクターの使い方は?

if UIScreen.instancesRespondToSelector(Selector("scale")) { 
    UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.mainScreen().scale); 
}else{...} 

を持っていたので、私はそれがためだかわからないんだけど、それは彼らが実際にUIScreen.mainScreen()を持つことができることを確認したかったように見えるまで変数.scale(?)。

.scaleを見ると、iOS 4.0以降に利用可能になっているようです。私たちはiOS 7をサポートしているので、これは必要ではないでしょうか?

とにかく、これは現在の問題ではありません。 これらの新しいセレクタインスタンシエーションやその他のもので、Xcode 7.3がSwift 3に向けて何百という警告を受けました。

Xcodeのは、私はこの変更したい:今まで

#selector(NSDecimalNumberBehaviors.scale)

Selector("scale")

を、私は変更されている他のすべてのセレクタは、「#selector(MyClass.hello)Selector("hello")を変更するように、論理的となっていますこのNSDecimal..はちょっと激しく聞こえますXcodeが正しいセレクタを選択するとは信用できますか?私は#selector(UIScreen.scale)を入力した場合はどこにでもUIScreen.scaleに接続NSDecimalNumberBehaviorsが..私はエラーを取得する見つけることができません。..

確かに私が知っている唯一のことは、if I CMDは+ここscaleをクリックしてくださいということです:NSDecimalNumberBehaviors.scale、ここに: UIScreen.mainScreen().scale私は別の場所に行きます。

+0

このような変更を行う前に、コードを書いた人(または何が起こっているか知っている人)と話すことを強くおすすめします。 – ZGski

+0

else条件には何がありますか?なぜスケールがUIScreenで呼び出せないのかわかりません。あなたが言ったように、iOS 4以降、このプロパティは利用可能であると公式文書に記載されています。 – Gustanas

+0

ZGski、彼らはもうここで働いていません。 @Gusta elseステートメントは単に 'UIGraphicsBeginImageContext(size)' – Sti

答えて

5

コメントに記載されているように、このコードは古いiOSバージョンをサポートしようとする痕跡の残ったものですが、これはもはや関連性がなくなっているだけでなく、Swift 。

UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.mainScreen().scale)に直接電話する - scaleプロパティは、Swiftでターゲット設定できるすべてのiOSバージョンに存在するため、確認する必要はありません。

実際、一般に、セレクタチェックを使用してAPIの可用性をテストすることは好ましくありません。セレクタは、ターゲティングするバージョンの下のバージョンに存在する可能性がありますが、動作が異なるプライベートAPIであるため、チェックは成功しますが、コードは正しく動作しません。これは、@available and #available systemがSwift 2に導入された理由です。

(バージョンベースの可用性チェックのもう1つの利点:OSバージョンがサポートを中止するほど十分に古い場合、コード内のすべてのサイトを見つけるのがずっと簡単です。あなたはクリーンアップすることができます。あなたがメソッド/プロパティは、ユニバーサルなったどのバージョンを覚えておく必要はありません。)


は、他のいくつかの理由であなたはUIScreen.scaleためSelectorを形成する必要がある場合は...あなたができますscaleはメソッドではなくプロパティであるため、#selector式を使用してSwift 2.2でそれを行います。 Swift 2.2では、#selectorは関数/参照を受け取り、プロパティの基礎をなすgetterメソッドまたはsetterメソッドへの参照を取得する方法はありません。あなたはまだ文字列からそのセレクタを構築する必要があります。

let scale = "scale" 
let selector = Selector(scale) 

をまたは文字列を渡す他のいくつかのダンスを行うが、直接Selector初期化子に、文字列リテラルを渡しません:警告を回避するために、一時的にリテラル文字列を隠しておく

let selector = Selector({"scale"}()) 

スウィフト3にはa special form of #selector for property getters/settersがありますが、まだ着陸していません。

3

私の2セント:

  • 1)迅速で安全な方法を検出することができセレクタ
  • 2)コンパイラのための新たなsntaxを持っているに基づいて:
    • N。

      .. 
           closeBtn.addTarget(self, action: #selector(doIt), for: .touchUpInside) 
          } 
      
      
      
      func doIt(_ sender: UIButton) { 
          print("touched") 
      } 
      
      
      func doIt() { 
          print("touched2 ") 
      
      } 
      

      A:すべてのPARAMの

    • のparamsタイプ
    • 結果の型の(ONLY純粋迅速で、それでは、今それを忘れてみましょう)

は4例を見てみましょう

「doIt」のあいまいな使用

B)

closeBtn.addTarget(self, action: #selector(doIt), for: .touchUpInside) 
} 


// func doIt(_ sender: UIButton) { 
//  print("touched") 
// } 


func doIt() { 
    print("touched2 ") 

} 

コンパイラは 署名

C)

closeBtn.addTarget(self, action: #selector(doIt(_:)), for: .touchUpInside) 
} 

func doIt(_ sender: UIButton) { 
    print("touched") 
} 


func doIt() { 
    print("touched2 ") 
} 

それが動作に一致することができる唯一の方法を検出することができるようにコンパイラが検出することができるように、それは、動作 が署名と一致できる唯一の方法です。

D)

closeBtn.addTarget(self, action: #selector(doIt), for: .touchUpInside) 
} 


func doIt(_ sender: UIButton) { 
    print("touched") 
} 

/* 
func doIt() { 
    print("touched2 ") 

} 
*/ 

それが動作すると:

  • コンパイラはあなたが正しいボタンの参照を取得しますデバッガで
    署名
  • を一致させることができます唯一の方法を検出することが可能です UIButton CODE(iOSライブラリ)は、
    スタック上のボタンアドレスをプッシュします。スタックフレームを作成します。
+0

です...何ですか?それは何であるはずですか? – holex

+0

あなたのことについての簡単な要約は、それらを使用することができます。あなたは間違っていると思いますか? – ingconti

関連する問題