2016-04-25 70 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("scale")

#selector(NSDecimalNumberBehaviors.scale)

到現在爲止,所有其他的選擇,我已經改變過的邏輯,像「改變Selector("hello")#selector(MyClass.hello),但這NSDecimal..聽起來有點激烈。我可以信任Xcode選擇正確的選擇器嗎?我找不到任何地方NSDecimalNumberBehaviors連接到UIScreen.scale ..如果我型#selector(UIScreen.scale)我得到一個錯誤..

我肯定知道的唯一的事情是,如果我CMD +點擊這裏scaleNSDecimalNumberBehaviors.scale,在這裏: UIScreen.mainScreen().scale我最終在不同的地方..

+0

我首先強烈建議在編寫代碼之前(或者至少有人可能知道發生了什麼事情)與之進行交流,然後再進行此類更改。 – ZGski

+0

什麼是其他條件?我不明白爲什麼無法在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 - 因此您的檢查將會成功,但是您的代碼將無法正常工作。這就是爲什麼在Swift 2中引入@available and #available system的原因。

(基於版本的可用性檢查的另一個好處:當操作系統版本變老足以讓您放棄支持時,在代碼中找到所有網站會更容易你可以清理你不必記住哪個版本,方法/屬性成爲普遍的。)


如果其他一些原因你需要形成一個UIScreen.scale ... Selector你可以在Swift 2.2中不使用#selector表達式,因爲scale是屬性而不是方法。在Swift 2.2中,#selector需要函數/引用,並且沒有辦法獲取對屬性底層getter或setter方法的引用。您仍然需要從字符串構造該選擇器。爲了解決該警告,藏匿字符串文字在臨時:

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

或者做傳遞一個字符串一些其他的舞蹈,但不直接傳遞一個字符串字面,在Selector初始化:

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

在Swift 3中會有a special form of #selector for property getters/setters,但它還沒有降落。

3

我的兩分錢:

  • 1)迅速對選擇
  • 2)編譯器能夠安全地檢測方法的新sntax基於:
    • ñ。的PARAMS
    • 類型的每個PARAM
    • 結果類型的(只在純迅速,現在讓我們忘了)

讓見第4的情況:

A)

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



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


func doIt() { 
    print("touched2 ") 

} 

'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代碼(在iOS庫中)按下了編譯器的堆棧上的按鈕地址
    es創建一個堆棧框架。
+0

ooo ...什麼?那應該是什麼? – holex

+0

只需回顧一下你可以使用它們。你認爲是錯的嗎? – ingconti