Swift type Casting using as Variance



On the initial stage type casting seems very ok, but on the long run it always bites us back. Lack of knowledge on type casting can drive us to some serious bugs those are nightmare for any developer, senior or junior. Swift has some very cool techniques for handling type casting, on its arsenal. One of them is is which is the type checker. Swift also provides us three as variance for type Casting. Some five minutes reading can save some long anxious hours. So let us not delay on type casting deep dive.

In the simplest term, type casting is to convert one type of instance to another. Type casting has two of its kind:

  • UpCast: Child to Parent conversion
  • DownCast: Parent to Child conversion

Type Casting on Swift:

Today we gonna talk about type casting, one little road I will never want to cross. Once you start to make a habit of crossing that road times to times, you will find yourself on deep pitfall very soon.
But anyway here we are on that difficult road, to understand:

as variance

On swift we use as as the type cast operatoras has three different variance based on operation they perform.

UpCast through as

as is the Upcast operator on Swift.

//: Playground - noun: a place where people can play

import UIKit

//: Up Cast
let label = UILabel(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
let labelView = label as UIView

On the above example we are upcasting the label, which itself is a UILabel, to its parent class UIView. The labelView is the UIView instance. As we know UILabel is inherited from UIView on UIKit framework. So this is a child to parent conversion.

DownCast through as?

as? is used on DownCast by an implicit way or a safe way. On successful conversion it will return the child object; on failure case will return nil. Basically an optional type cast.

//: Playground - noun: a place where people can play

import UIKit

//: Up Cast
let label = UILabel(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
let labelView = label as UIView


//: Down cast
let childLabel = labelView as? UILabel // success
childLabel?.text // prints "Hello"

let childButton = labelView as? UIButton // fails
childButton?.tintColor // prints nil

As we can see on the above example, label is type casted to UIView. Then we start to convert the labelView again to UILabel through as? which successes and we can print the text property of UILabel. But when we try to convert the labelView to UIButton, which is also a subclass of UIView, through as? we are getting a nil. as? is down casting in a safer way.

Force downcast through as!

as! is used for forced downcast. Will potentially crash the app when force downcast will return nil.

//: Playground - noun: a place where people can play

import UIKit

//: Up Cast
let label = UILabel(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
label.text = "Hello"
let labelView = label as UIView


//: Down cast
let childLabel = labelView as! UILabel
childLabel.text

let childButton = labelView as! UIButton
childButton.tintColor //error: Execution was interrupted, reason: signal SIGABRT.

The most dangerous type casting operator.

On the above example when we are force down casting the labelView to UILabel then it seems very ok, but things will get messy when we try to convert the wrong type cast. Force down casting the labelView to UIButton causes a nil instance. And finally accessing the property of a nil instance causing the crash.

By the way we have already a blog post on optional, force unwrapping and etc. Fell free to have a look on that.

Type checking through is

is is the type check operator.

//: Playground - noun: a place where people can play

import UIKit

let label = UILabel(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
let valid = label is UIView // true

On the above example we are just checking if the label is a UIView or not. Finally returns a Bool value.

Best practice

This is a heavily opinion based practice, you are always welcome to discard or embrace the following practice. But I can confirm life will be much more easier if you start to follow the practice for type casting.

The very first practice is to avoid type cast. But unless you can’t

  • It is almost ok to use as when it comes to upcasting.
  • For down casting the very first and last choice should be to use as?, as it will give us the chance to verify at-lest the return instance is nil or not.
  • Never use as! for down casting, even if you are pretty sure.

The root of this blog post is from my github q/a

Leave a Reply

Notifications for mobidevtalk! Cool ;) :( not cool