2016-04-25 113 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

相关问题