Up until now I have had this code
if UIScreen.instancesRespondToSelector(Selector("scale")) {
UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.mainScreen().scale);
}else{...}
I didn't write this code, so I'm not sure what it's for, but it looks like they wanted to verify that UIScreen.mainScreen()
in fact can have the variable .scale
(?).
When looking at the .scale
, it looks to me like this has been available since iOS 4.0. Since we support down to iOS 7, this shouldn't be necessary, right?
Anyway, this is not the current problem. I am now having hundreds of warnings due to Xcode 7.3 towards Swift 3 with these new selector-instantiations or whatnot.
Xcode wants me to change this:
Selector("scale")
into
#selector(NSDecimalNumberBehaviors.scale)
Until now, all other selectors I have changed have been logical, like "change Selector("hello")
into #selector(MyClass.hello)
, but this NSDecimal..
sounds a bit drastic. Can I trust Xcode to pick the right selector? I can't find NSDecimalNumberBehaviors
anywhere connected to UIScreen.scale.. If I type #selector(UIScreen.scale)
I get an error..
The only thing I know for sure is that if I CMD+click scale
here: NSDecimalNumberBehaviors.scale
and here: UIScreen.mainScreen().scale
I end up in different places..
As noted in comments, this code is a vestigial remnant of attempts to support old iOS versions that not only are no longer relevant, but can't even be targeted when developing in Swift.
Just call UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.mainScreen().scale)
directly — the scale
property exists on all iOS versions that you can target with Swift, so there's no need to check for it.
In fact, in general it's not a good idea to test for API availability using selector checks. A selector may exist on a version below the one you're targeting, but be private API with different behavior — so your check will succeed, but your code will not behave correctly. This is why the @available
and #available
system was introduced in Swift 2.
(Another upside of version-based availability checking: when an OS version gets old enough for you to drop support, it's much easier to find all the sites in your code that you can clean up. You don't have to remember which version which method/property became universal in.)
If for some other reason you need to form a Selector
for UIScreen.scale
... you can't use the #selector
expression to do that in Swift 2.2, because scale
is a property, not a method. In Swift 2.2, #selector
takes a function/reference, and there's no way to get a reference to the underlying getter or setter method of a property. You'd still need to construct that selector from a string. To get around the warning, stash the string literal in a temporary:
let scale = "scale"
let selector = Selector(scale)
Or do some other dance that passes a string, but doesn't directly pass a string literal, to the Selector
initializer:
let selector = Selector({"scale"}())
In Swift 3 there'll be a special form of #selector
for property getters/setters, but it hasn't landed yet.
my two cents:
let see 4 cases:
A)
..
closeBtn.addTarget(self, action: #selector(doIt), for: .touchUpInside)
}
func doIt(_ sender: UIButton) {
print("touched")
}
func doIt() {
print("touched2 ")
}
Ambiguous use of 'doIt'
B)
closeBtn.addTarget(self, action: #selector(doIt), for: .touchUpInside)
}
// func doIt(_ sender: UIButton) {
// print("touched")
// }
func doIt() {
print("touched2 ")
}
it works, as compiler is able to detect the ONLY method that can match the signature
C)
closeBtn.addTarget(self, action: #selector(doIt(_:)), for: .touchUpInside)
}
func doIt(_ sender: UIButton) {
print("touched")
}
func doIt() {
print("touched2 ")
}
it works, as compiler is able to detect the ONLY method that can match the signature.
D)
closeBtn.addTarget(self, action: #selector(doIt), for: .touchUpInside)
}
func doIt(_ sender: UIButton) {
print("touched")
}
/*
func doIt() {
print("touched2 ")
}
*/
it works and:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With