muvaaa
muvaaa

Reputation: 600

Swift return Self in callback

Is it possible to return Self in a super class method in Swift: For example:

public class C {
    let name: String
    init(name:String) {
        self.name = name
    }

    public class func getByID(id:String, cb:(C->Void)) {
        // do something async
        cb( C(name: "Some name") )
    }
}

class CC: C {
}

CC.getByID("someId") { c in
    if let c = c as? CC {
        // I want this to happen
        println("c is of type CC")
    } else {
        println("c is not of type CC")
    }
}

If I replace cb type to (Self->Void) I get a compile error saying

'Self' is only available in a protocol or as the result of a class method; did you mean 'C'?

Upvotes: 1

Views: 460

Answers (1)

rintaro
rintaro

Reputation: 51911

In class method, you can use self as the class itself.

And, in this case, you need to mark your initializer as required.

public class C {
    let name: String
    required public init(name:String) {
//  ^^^^^^^^ HERE    
        self.name = name
    }

    public class func getByID(id:String, cb:(C->Void)) {
        // do something async
        cb( self(name: "Some name") )
        //  ^^^^ HERE
    }
}

ADDED:

But is there any way to avoid downcasting to class CC in callback?

It's difficult, because we cannot use Self in the type of the parameters.

The best we can is something like this:

public class C {
    let name: String
    required public init(name:String) {
        self.name = name
    }

    public class func getByID<T: C>(id:String, cb:(T -> Void)) {
        if let instance = self(name: "Some name") as? T {
            cb(instance)
        }
        else {
            // `self` is not the type the callback expecting.
            // error handling if required.
        }
    }
}

Then you call:

CC.getByID("someId") { (c: CC) in
    println("c is of type CC")
}

Upvotes: 1

Related Questions