How to cast an object from its base class into its subclass

11,943

Solution 1

If it's an instance of PFUser, and not an instance of User stored in a variable of PFUser type, no it's not possible.

You can cast an instance of a class to one of its superclasses, but you cannot do the other way (unless the cast type is the actual instance type).

I suggest to implement an initializer in User, taking a PFUser instance as parameter - if that's possible.

However, although I never attempted to do so, I think inheriting from PFUser you'll just run into troubles, as my understanding is that this class is not designed to be inherited as it is for PFObject. I'd suggest looking into making PFUser a property of User - that way you can just assign as needed.

Solution 2

This type of casting is a downcast. Given an instance of a certain base class where you know there exist subclasses, you can try to downcast with the typecast operator as:

class Base {}
class Derived : Base {}

let base : Base = Derived()
let derived = base as Derived

Keep in mind though, that a downcast can fail:

class Base {}
class Derived : Base {}
class Other : Base {}

let base : Base = Other()
let derived = base as Derived  // fails with a runtime exception

You can try a downcast using the optional form of the type as operator as?.

class Base {}
class Derived : Base {}
class Other : Base {}

let base : Base = Other()

// The idiomatic implementation to perform a downcast:

if let derived = base as? Derived {
    println("base IS A Derived")
}
else {
    println("base IS NOT A Derived")  // <= this will be printed.
}

Solution 3

This can also be done by using the following:

object_setClass(baseClass, derivedClass.self)

However it is worth nothing that this uses the objc-runtime library which can introduce odd crashes if not used correctly.

Share:
11,943
grabury
Author by

grabury

Updated on July 29, 2022

Comments

  • grabury
    grabury almost 2 years

    I have a class User which is a subclass of class PFUser:

    class User: PFUser {
     var isManager = false
    }
    

    In one of my methods I receive a PFUser object and I want to cast it to a User object

    func signUpViewController(signUpController: PFSignUpViewController!, didSignUpUser user: PFUser!) {
     currentUser = user
    }
    

    Is this possible?

  • fingia
    fingia about 4 years
    this definitely should be the accepted answer because IT IS POSSIBLE to do what the user is asking. It's called downcasting. docs.swift.org/swift-book/LanguageGuide/TypeCasting.html#ID3‌​41
  • picciano
    picciano almost 3 years
    Seems like dancing on a case of 80 year old dynamite, but worked perfect for what I needed to do.