2016-11-10 10 views
3

複数の(2+)引数を持つセレクタを呼び出そうとしています(引数の数を特定できます)。しかし、セレクタはコンパイル時には不明です(実際にはNSSelectorFromStringで生成されます)。SwiftにNSInvocationの代替手段はありますか?

Objective-Cでは、私は呼び出しを作成し、それに引数を設定して呼び出すことができました。しかしこれはSwiftでは利用できません。これを回避する方法はありますか? ように:

let obj = SomeClass() 
let selector = NSSelectorFromString("arg1:arg2:arg3:") //selector, arguments known only at runtime 
//invoke selector 
+0

あなたが解決しようとしている問題はなんですか? – Alexander

+0

申し訳ありませんが、私はクライアントのために働いています。しかし、私はそれを私の最善の方法で説明しようとします。私は必要に応じて構成することができる構成ファイルの助けを借りてビューを構成する必要があります。つまり、可能な構成の一覧(それぞれがさまざまな方法にアクセスしようとしている)が大きくなっています。はい、ケースごとに管理することができます(ケースをメソッドにマッピングする)が、これを試して管理するための汎用ソリューションを使用しようとしています。 – Aswath

+0

この種のコードの動的性は、通常、アーキテクチャが悪い(違反していない)ことの結果です。非常に特殊な例外がいくつかありますが、95%では 'NSInvocation'を使用する必要はなく、対話型であってもCであってはいけません。 1つの可能な解決策は、辞書でクロージャーという名前が付けられていますが、それは少しコード臭です。 – Sulthan

答えて

0

私は怖いがスウィフトでこれを行う方法はありません。

ただし、動的呼び出しを管理するObjective-Cクラスがあります。そこにNSInvocationを使用することができます。

3

スウィフト3.1

NSInvocationはなく、楽しいだけの練習として、絶対にない本格的なアプリケーションのために、動的に使用することができます。より良いのはalternativesです。

class Test : NSObject 
{ 
    var name : String? { 
     didSet { 
      NSLog("didSetCalled") 
     } 
    } 

    func invocationTest() { 
     let invocation : NSObject = unsafeBitCast(method_getImplementation(class_getClassMethod(NSClassFromString("NSInvocation"), NSSelectorFromString("invocationWithMethodSignature:"))),to:(@convention(c)(AnyClass?,Selector,Any?)->Any).self)(NSClassFromString("NSInvocation"),NSSelectorFromString("invocationWithMethodSignature:"),unsafeBitCast(method(for: NSSelectorFromString("methodSignatureForSelector:"))!,to:(@convention(c)(Any?,Selector,Selector)->Any).self)(self,NSSelectorFromString("methodSignatureForSelector:"),#selector(setter:name))) as! NSObject 
     unsafeBitCast(class_getMethodImplementation(NSClassFromString("NSInvocation"), NSSelectorFromString("setSelector:")),to:(@convention(c)(Any,Selector,Selector)->Void).self)(invocation,NSSelectorFromString("setSelector:"),#selector(setter:name)) 
     var localName = name 
     withUnsafePointer(to: & localName) { unsafeBitCast(class_getMethodImplementation(NSClassFromString("NSInvocation"), NSSelectorFromString("setArgument:atIndex:")),to:(@convention(c)(Any,Selector,OpaquePointer,NSInteger)->Void).self)(invocation,NSSelectorFromString("setArgument:atIndex:"), OpaquePointer($0),2) } 
     invocation.perform(NSSelectorFromString("invokeWithTarget:"), with: self) 
    } 
} 
関連する問題