Reputation: 191
I have this code:
class Dark: NSObject {
class var className: String {
return NSStringFromClass(self)!.componentsSeparatedByString(".").last!
}
var success = 0
class func devour<T: Dark>(params: Int) -> T {
var s = T()
return assign(s, params: params)
}
class func assign<T: Dark>(item: T, params: Int) -> T{
if item.dynamicType === self {
item.success = params
}
return item
}
}
class Black: Dark {
}
class Violet: Dark {
}
Black.className // returns "Black"
Violet.className // returns "Violet"
The problem occurs when I do this:
var ret = Black.devour(5)
ret.success //returns 0 which I expect to be 5
ret.self // returns {Dark success 0} which I expect to be {Black success 0}
The problem here is that when the subclass uses the inherited method devour, it returns an object of type Dark
. I want to be able to return the subclass type and not the superclass type when calling devour. Example when I do:
var ret = Black.devour(5)
The class of ret should be of class Black
and not of class Dark
.
I hope someone can help me on this. Im really out of ideas. Thanks! I want to avoid chaining and I consider it last resort.
Upvotes: 10
Views: 6237
Reputation: 191
It turns out I was able to do a work around; Thanks to the answer to this question: Cast to typeof(self).
All I need to do is create a method which returns an object of type Self.
first, I created a class that creates an instance of the base class and return it as an instance of AnyObject.
class func createDark() -> AnyObject {
var black = Black()
return black
}
When I return an instance of Black
it automatically casts it into AnyObject since it was the specified return type of the method (I honestly just figured this out and this saved me).
Then I created a helper method that calls createDark()
and assigns properties/attributes to the instance:
class func prepare<T: Dark>(params: Int) -> T{
var dark = createDark() as T
dark.assign(params)
return dark
}
I used generic type which is of Dark
type or its subclass as a return type.
Then I did this:
class func devour(params: Int) -> Self {
return prepare(params)
}
by specifying Self
as return type, It automatically casts it to type of self which can be of Dark
type or any class that inherits it.
My final code looks like this:
class Dark: NSObject {
var success = 0
func assign(params: Int) {
if self.dynamicType === self { // I dont really have to do this anymore
self.success = params
}
}
class var className: String {
return NSStringFromClass(self)!.componentsSeparatedByString(".").last!
}
class func createDark() -> AnyObject {
var black = Black()
return black
}
class func prepare<T: Dark>(params: Int) -> T {
var dark = createDark() as T
dark.assign(params)
return dark
}
class func devour(params: Int) -> Self {
return prepare(params)
}
}
to check if it solved the problem:
var ret = Black.devour(5)
ret.success //now returns 5 as expected
ret.self // now returns {Black success 0} as expected
works as expected!
Upvotes: 8