grabury
grabury

Reputation: 5599

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

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?

Upvotes: 12

Views: 21276

Answers (3)

Charlton P
Charlton P

Reputation: 2274

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.

Upvotes: 8

CouchDeveloper
CouchDeveloper

Reputation: 19174

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.
}

Upvotes: 17

Antonio
Antonio

Reputation: 72810

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.

Upvotes: 7

Related Questions