S_kar S_kar - 4 months ago 14x
Swift Question

Confusion about type casting in swift

I was toying in the playground in xcode 7.3.1 with swift. I am a bit confused about the type casting in swift.

So, here is a bit of code that I tried.

class MediaItem {
var name: String
init(name: String) {
self.name = name

class Movie: MediaItem {
var director: String
init(name: String, director: String) {
self.director = director
super.init(name: name)

class Song: MediaItem {
var artist: String
init(name: String, artist: String) {
self.artist = artist
super.init(name: name)

var movieItem = Movie(name: "GOT", director: "RRMartin")

movieItem.dynamicType //Movie.Type
(movieItem as? MediaItem).dynamicType //Optional<MediaItem>.Type
var someItm = movieItem as! MediaItem //Movie
someItm.dynamicType //Movie.Type

I've shown the output from the playground in the comment. Here you can see the type in each line.

Now according the docs of apple,
The conditional form, as?, returns an optional value of the type you are trying to downcast to.
As per the docs, I am trying to downcast to MediaItem, and I am getting the MediaItem as optional type.

But when I use force unwrap(that is
) the returned type is
. But I wanted it to be

Also, another thing to notice is that, the type is actually changed. Some data are actually truncated. Because when I tried to access the
property which is present in the Movie, I cannot access it. As I've downcast it.

So, if the type is downcast, why the returned type is
? Shouldn't it be

So, my question is this, when I type cast some derived class(
) to base class(
), shouldn't the converted type be base class(


dynamicType tells you what the underlying type of the object is. It doesn't tell you what the type of var currently referencing that object is.

For instance:

let a: Any = 3
a.dynamicType // Int.Type

Swift, of course, keeps track of these underlying types which is what allows you to later downcast a MediaItem to a Movie (if that is what it really is).

The confusion for you came when you did:

(movieItem as? MediaItem).dynamicType  //Optional<MediaItem>.Type

An Optional is it's own type. It is an enumeration with two values: .None and .Some(T). The .Some value has an associated value that has its own dynamic type. In your example, when you asked for the dynamicType, it returned the underlying type of the Optional which is Optional<MediaItem>.Type. It didn't tell you what the dynamic type of the value associated with that Optional is.

Consider this:

let x = (movieItem as? MediaItem)
x.dynamicType    // Optional<MediaItem>.Type
x!.dynamicType   // Movie.Type