-1

I encountered little unusual down casting failure.

I have a class Vehicle in FrameworkA

FrameworkA

open class Vehicle {
    open var name: String = ""
}

And I subclassed this Vehicle class in other project.

Project

import FrameworkA

class Car: Vehicle {
    var maker: String = ""
}

And I tried downcast like this

let vehicle = Vehicle()
let car = vehicle as! Car

If they are in same framework(or same project namespace), there is no problem, but in this case down casting from Vehicle to Car fails.

The error message was just like below.

Could not cast value of type 'FrameworkA.Vehicle' (0x1070e4238) to 'Project.Car' (0x10161c120).

So I had to use extension of Vehicle class and used associatedObject. Is there any way to subclass and downcast?

Ryan
  • 4,799
  • 1
  • 29
  • 56
  • 3
    Update your question with the actual code causing the error and post the exact (not "somewhat") error. – rmaddy Dec 21 '16 at 23:23
  • Updated the error message. Code was exactly what it was. – Ryan Dec 21 '16 at 23:37
  • Is your Vehicle class declared as public? –  Dec 21 '16 at 23:39
  • 1
    Which line exactly is giving the error? – rmaddy Dec 21 '16 at 23:42
  • 1
    @rmaddy Added the case. it happens exact line of down casting `as! Car`. if I use optional like `as? Car`, the `car` will be nil. – Ryan Dec 21 '16 at 23:49
  • BTW - you state that if the two classes are in the same framework, the cast works fine. Are you sure about that? It's simply not possible for the code you posted. – rmaddy Dec 22 '16 at 00:13
  • That's what I'm trying to figure out. As you answered here it shouldn't work. I even tested it in playground and confirmed it doesn't work. However I have a app already in app store and works nicely which I believe there is same logic. I'll keep update as soon as I find how it is going. – Ryan Dec 22 '16 at 00:46

2 Answers2

3

Of course your code fails. It has nothing to do with using a framework or not.

Car is a special kind of Vehicle. You are creating a Vehicle object. You then try to cast it to a Car. But it's not a Car. It's a Vehicle.

The following works:

let car = Car()
let vehicle: Vehicle = car

That's fine because you create a Car which is also a Vehicle.

You can also do this:

let vehicle: Vehicle = Car()
let car = vehicle as! Car

That works because even though vehicle is declared as a Vehicle, the object it is actually pointing to is a Car.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
2

This isn't a downcast... Car is a Vehicle, but Vehicle isn't a Car.

Daniel Hall
  • 13,457
  • 4
  • 41
  • 37