Imagine that you have a number of sub classes (say perhaps of UITableViewCell
) and you want some code to do something differntly for each kind of subclass. Recently I came across some code in a project that did it like this:
func whatIs(it: UITableViewCell) -> String {
if _ as? TableViewCellSubclassA {
return "This is an instance of Subclass A"
} else if _ as? TableViewCellSubclassB {
return "This is an instance of Sublcass B"
}
//More code followed in the same form
}
This was relatively hard to read. In addition, I didn’t like the code smell of the _ as?
part. That structure in swift has always made me thing that something could have been worded differently. Now, to be fair, in early Swift, I believe this was the only way to really do something like this. However, now we have the is
keyword to help us associate a class instance with a class type. So the code can be rewritten somewhat more clearly:
NB the is
keyword only works with classes and subclasses. If you have other types you still need to use some variation of as
.
The use of the is
keyword is an improvement for sure over the let _ as?
construction as far as readability goes. I was still unhappy with all of the if...else if...else if
stuff. I was also noticing that in the legacy code there wasn’t a final else
so if a future developer adds a subclass that doesn’t get handled by the code, the system will happy do something undefined (or maybe crash). So, for the final variation that I think addresses the issues of readability and future proofing, I moved to a Swift switch
statement and the is
keyword with a default
case.
The use of an assertion will cause the code to crash during development runs (when it can be addressed) but will not cause the code to crash in a production environment. This way when the future developer adds a subclass they don’t need to remember to also update this function, the compiler will tell them.
If you would like to play with this function and some of the variations I used, I am linking to a playground that demonstrates the code.