Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to get a _stable_ generic class name in Swift?

Tags:

swift

Getting the name of a class in Swift is pretty easy like so:

import Foundation

class Gen<T> {
    init() { }
}

func printName(obj: AnyObject) {
    dump(NSStringFromClass(obj.dynamicType))
}

let a: Gen<String> = Gen()
let b: Gen<Int> = Gen()
printName(a)
printName(b)

However if you run the above code twice, it will not produce the same result.

So is there a way to implement printName (get at a specialized generic class's name) in a stable way? That is multiple runs of the code prints the same string for the same class?

I'm using the latest Xcode beta.

Some extra requirements:

  • The number of classes that will be passed to printName is high.
  • There maybe more than one generic class, but not a lot.
like image 965
chakrit Avatar asked Jan 30 '15 09:01

chakrit


2 Answers

Sorry to disappoint, but this does not seem to be possible, unless you actively write a new compiler.

Check this source out. The author describes it quite well: Note that the isa pointer of the two objects is not identical, even though both are an instance of WrapperClass. Evidently, a specialization of a generic class is a separate class at runtime.

What I was also playing around with was @objc, but this is just changing the namespace of the class, but obviously has no influence on the class name.

like image 56
Marco Pashkov Avatar answered Nov 16 '22 15:11

Marco Pashkov


New starting from Xcode 6.3 beta 1

Good news! Starting from 6.3 you can do:

toString(Gen<Int>())

And that'd print: Gen<Swift.Int>

OLD Answer:

If the scope can be reduced to T: AnyObject then you can implement it as follows:

class Gen<T: AnyObject> {
    var className: String {
        return "Gen<\(NSStringFromClass(T.self))>"
    }
}
like image 6
fz. Avatar answered Nov 16 '22 16:11

fz.