Swiftで動的にクラス作ってメソッド呼ぶ。しかも全く型情報がない状態で。要はjavascriptみたいなことがしたい

まとめ

  • NSSClassFromString使う
  • 引数が3つ以上だとperformSelectorは使えない
  • SwiftだとNSInvocationは使えないので代わりにIMPを使う
  • Class methodとInstance methodで呼び方ちょっと違う
  • performSelectorの返り値の型はUnmanaged<AnyObject>takeUnretainedValueを使う

引数が多いときのやり方で参考にしたobjcのコード

github.com

+ (id)initGraphRequestWithGraphPath:(NSString *)graphPath{
    Class FBSDKGraphRequestClass = NSClassFromString (@"FBSDKGraphRequest");
    id graph = [FBSDKGraphRequestClass alloc];
    
    SEL aSelector = NSSelectorFromString(@"initWithGraphPath:parameters:");
    IMP imp = [graph methodForSelector:aSelector];
    id (*func)(id, SEL, id, id) = (void *)imp;
    
    graph = func(graph, aSelector, graphPath, @{});
    return graph;
}

www.b2cloud.com.au

Unmanaged<AnyObject>の取り出し方

stackoverflow.com

var unmanagedObject: Unmanaged = someFunctionThatReturnsAnUnmanagedObject() var newValue: Type = unmanagedObject.takeRetainedValue as Type

takeRetainedValueってやつを使うみたい。でも、アプリがEXC_BAD_ACCESSかなんかだったかで落ちた。 takeUnretainedValueだったら大丈夫だった。

ふーむ。allocしたのに、release漏れてるからとかなんだろうか。Swiftでは普通allocなんて書かないからあんまり普段考えないことだけど。

SwiftでIMPを呼ぶ

stackoverflow.com

unsafeBitCastを使う。

NSClassFromStringでClass methodを呼ぶ

stackoverflow.com