現時点でSwift流のやり方は分かってない。
従来からあるNSClassFromString()、NSStringFromClass()を使う。
オブジェクトからクラス名を取得
class A {} NSStringFromClass(A.self) // -> "__lldb_expr_13.A"
空間名(という表現でいい?)がAの前につく様だ。
@objc(A) class A: NSObject {} NSStringFromClass(A.self) // -> "A"
NSObjectから継承し@objc(A)を付けることで"A"として得られる。
実はNSStringFromClass()を使わなくても得られる。
NSObjectも関係ない。
Swift流ということでいい?
class A {} let a = A() String(describing: type(of: a)) // -> "A"
クラス名からオブジェクトを生成
@objc(A) class A: NSObject { required override init() {} } if let t = NSClassFromString("A") as? A.Type { _ = t.init() // -> Aのオブジェクト }
- 前に書いた様にrequiredを付けたinit()メソッドが必要。 katsuyoshi.hatenadiary.com
- NSClassFromString()で取得できるのはNSObjectを継承したクラスじゃないといけない。
- そのメソッドを得るには@objc()でobjcのメソッドを扱うことを明示しないといけない。
- NSClassFromString("A") as? A.TypeとクラスAであることを付加しないとinit()を受け付けてくれない。
Aの派生クラスのみ対象とできる。
@objc(A) class A: NSObject { required override init() { super.init() debugPrint(String(describing: Self.self)) } } @objc(B) class B: A { } if let t = NSClassFromString("A") as? A.Type { _ = t.init() // -> Aのオブジェクト } if let t = NSClassFromString("B") as? A.Type { _ = t.init() // -> Bのオブジェクト }
とここまで、正解かどうかは置いておいて、現時点での認識。