在Swift中有没有NSInvocation的替代方案?

Asw*_*ath 3 selector nsinvocation ios swift swift3

我正在尝试调用一个带有多个(2+)参数的选择器(可以确定参数的数量).但是,选择器在编译时是未知的(实际上是使用NSSelectorFromString生成的).

在Objective-C中,我可以创建一个调用并为其设置参数并调用它.但这在Swift中不可用.有没有办法解决?喜欢:

let obj = SomeClass()
let selector = NSSelectorFromString("arg1:arg2:arg3:") //selector, arguments known only at runtime
//invoke selector
Run Code Online (Sandbox Code Playgroud)

Kam*_*l.S 7

Swift 3.1

NSInvocation可以动态使用,但仅作为有趣的练习,绝对不适用于严肃的应用程序.有更好的选择.

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)
    }
}
Run Code Online (Sandbox Code Playgroud)


Mar*_*ino 5

恐怕 Swift 中没有办法做到这一点。

然而,您可能有一个 Objective-C 类来管理您的动态调用。你可以NSInvocation在那里使用。