6552


swiftに関して質問です。  
自作したクラスのインスタンスを生成する方法として、通常は下記のように生成できます。

[code]

    let vc = HogeViewController()
    
[/code]

ここで、自作したクラスを **HogeViewController** とした時、これを **文字列(String型)から生成する**
場合にどうすればいいかわかりません。どなたかご教授頂けないでしょうか。

下記は理想なのですが、エラーになります。

[code]

    let strVC:String = "HogeViewController"
    let cls:AnyClass = NSClassFromString(strVC)
    let vc:AnyObject = cls()            // この行でエラー
    
[/code]

※エラー文

> ‘AnyObject’ cannot be constructed because it has no accessible initializers

実際に使用する場合にはクラス名の文字列は固定値ではなく、動的に変化する予定です。  
よって、特定の自作クラスでキャストすることは想定していません。  
コンストラクタはデフォルトを想定しています。  
なお、Objective-Cの場合は下記でできます。

[code]

    NSString* strVC = @"HogeViewController";
    Class cls = NSClassFromString(strVC);
    id vc = [[cls alloc] init];
    
[/code]

よろしくお願いいたします。


CC BY-SA 3.0
2015-02-16T05:48:09.923
6549
2015-02-16T07:29:30.257
2015-02-16T07:15:49.973
7364
7364
question
objective-c swift
swiftでクラス名からインスタンスを生成する方法


以下で動作することを確認しました。  
ポイントは、`@objc` をつけることと、 `class Foo : NSObject` で NSObject を継承していることです。（継承するのは
NSObject から継承したクラスでも大丈夫です）

[code]

    @objc(Foo)
    class Foo : NSObject {
        func bar() {
            println("bar")
        }
    }
    
    var cls:NSObject.Type = NSClassFromString("Foo") as NSObject.Type
    var foo:Foo = (cls() as Foo)
    foo.bar()    // -> `bar` が出力される
    
[/code]


CC BY-SA 3.0
2015-02-16T06:21:16.960
6552
2015-02-16T06:28:04.817
2015-02-16T06:28:04.817
5106
5106
6549
answer


[`NSClassFromString`](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/InteractingWithObjective-
CAPIs.html#//apple_ref/doc/uid/TP40014216-CH4-XID_36)
のドキュメントの記述によると、「クラスがロードされていなければ nil となる」
と書かれており、動かないのは、クラスがロードされていないのか、指定された名前のクラスが見つからないかのどちらかだと思います。

StackOverflow のこの質問 "[NSClassFromString returns
nil](https://stackoverflow.com/questions/2227085/nsclassfromstring-returns-
nil)" によると、 ビルド設定の `Other Linker Flags` に、 `-ObjC` を付けることで回避ができるようです。
ただ、これのために `-ObjC` フラグを付けるのは大げさなので、同じ要領だとすると
[`@objc(クラス名)`](https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Miscellaneous/Foundation_Functions/index.html#//apple_ref/c/func/NSClassFromString)を付けることでも行けると思います。要は、ObjectiveC
のコードからいつでもアクセスできる状態にすればよいので。


CC BY-SA 3.0
2015-02-16T06:28:38.000
6553
2015-02-16T06:28:38.000
2017-05-23T12:38:55.250
-1
4978
6549
answer


自己解決したので、その際のコードを下記に記載します。  
下記コードは「クラス名からViewControllerを生成して、UINavigationControllerにセットする」内容です。  
前提として、HogeViewControllerはUIViewControllerの継承クラスで、@objc(HogeViewController)を付加していること。

[code]

    var strVC:String = "HogeViewController"
    var cls:NSObject.Type = NSClassFromString(strVC) as NSObject.Type
    var vc:UIViewController = cls() as UIViewController
    let navi:UINavigationController = UINavigationController(rootViewController: vc)
    
[/code]

上記コードのstrVCが動的に変化しても、そのクラスがロードされていれば正しく画面遷移します。


CC BY-SA 3.0
2015-02-16T07:29:30.257
6558
2015-02-16T07:29:30.257
7364
6549
answer