Keywords
Swift 2.0, type casting, as, as!, as?
Solution
Upcasting using as
Upcasting happens when you are trying to cast from a derived
class to a base class. This will always succeed. The following is an example
using the as keyword to perform upcasting:
let btn = UIButton()
let view = btn as UIView
The as keyword can
also be used for literal casting:
let strNum1 = 2.4 as
Float
let strNum2 = 2.4 as
Int
Downcasting using as?
Downcasting happens when you are trying to cast from a base class
to a derived class. This may not always succeed.
Consider the following code snippet:
@IBAction func
btnClicked(sender: AnyObject) {
}
In this action for a Button view, you have an argument named sender of type AnyObject. If you want to cast this to a UIButton, you may attempt to use the as keyword:
@IBAction func
btnClicked(sender: AnyObject) {
let btn =
sender as UIButton
}
However, the compiler will flag this as an error as the type
casting may fail. Instead, you have to use as?
keyword to perform a downcast, like
this:
@IBAction func
btnClicked(sender: AnyObject) {
//---downcasting---
let btn =
sender as? UIButton
print(btn?.titleLabel?.text)
}
The as? keyword tries
to perform a downcast, and returns a value of the specified type if it
succeeds, or nil if it fails. Hence,
the result of the above casting is a UIButton?
(optional). To use the btn constant,
you need to unwrap it using the ? (
or !) operator.
A safer way to deal with downcasting is to wrap it using the if let statement, like this:
@IBAction func
btnClicked(sender: AnyObject) {
//---downcasting---
if let btn =
sender as? UIButton {
//---casting
succeeds---
print(btn.titleLabel?.text)
} else {
//---casting
failed---
}
}
}
Notice that using the if
let statement you now don’t have to unwrap the btn constant as it is now a UIButton
and not UIButton?.
Downcasting using as!
If you are very sure that the casting will always succeed, you
can use the as! keyword, like this:
@IBAction func
btnClicked(sender: AnyObject) {
let btn =
sender as! UIButton
print(btn.titleLabel?.text)
}
The result of the casting is a value of type UIButton. However, if you are not careful, and the casting fails,
it will crash your app:
@IBAction func
btnClicked(sender: AnyObject) {
//---casting
will fail and your app will crash!---
let tableView =
sender as! UITableView
}
When using the as!
keyword, you can also specify the destination type to be an optional, consider
the following:
var dict = [Int:Any]()
dict[1] = "Gold"
dict[2] = "Silver"
dict[3] = "Bronze"
print(dict[1] as! String) //---Gold---
print(dict[1] as!
String?) //---Optional("Gold")---
The last statement converts the specified item in the dictionary
to a String? (optional).