SwiftのクラスにはObjective-CのNSObjectにあったclassNameプロパティのようなものがないので、文字列でクラス名を取得するには工夫が必要。
Objective-Cのメソッドを使ってNSStringFromClass(String)のようにする。これを実行するにはFoundationをインポートする必要がある。
※Stringは構造体であってクラスではないが、Swiftでは構造体やクラスはタイプという上位概念で包含され様々な点で似た振る舞いをする。
ただし、独自に定義したクラスではランタイムモジュールを含めた修飾が定義したクラス名の前につくのでこれを削除する必要がある。結局、以下のようになる。
import Foundation
func className(type: AnyClass) -> String {
print("AnyClass : ", terminator:"" )
// print( NSStringFromClass(type) ) // "__lldb_expr_198.Root"
return NSStringFromClass(type).componentsSeparatedByString(".").last!
}
class Root { }
className( Root ) // "Root"
単にクラス名を出力するだけであればprint( Root.self )のようにしても"Root"という結果が得られるのだが、これはprintメソッドが内部でクラス名文字列を取り出す処理を行っているだけのようだ。文字列として取り出して使うことはできない。
インスタンスからそのクラス名を取り出すには、同様に出力だけならprint( Root() )でできる。が、ちゃんとするには先ほどのメソッドに Root().dynamicType を渡すとよい。
func className(o: AnyObject) -> String {
print("AnyObject : ", terminator:"" )
return className(o.dynamicType)
}
let root = Root()
className(root)
型名(クラス名)+.self あるいは、インスタンス+.dynamicType をStringに変換するとクラス名を文字列として取得可能。 print(...) でクラス名を出力するのはこの機構を使っていたんだね。
String(root.dynamicType) // "Root"
String(Root.self) // "Root"