雨燕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)
}
}
你试图解决什么问题? – Alexander
我很抱歉,但我正在为客户工作。但我会尽力描述它。我必须在配置文件的帮助下配置一个视图,该配置文件可以根据需要进行配置。也就是说,可能的配置列表(每个尝试访问许多不同的方法)都很大。是的,他们可以按情况进行管理(将案例映射到方法),但我试图使用通用解决方案来尝试和管理此问题。 – Aswath
这种代码的动态性通常是糟糕的体系结构(没有违法)的结果。有一些非常特殊的例外情况,但在95%的情况下,您不需要使用'NSInvocation',即使在Objective-C中也不应该使用。一种可能的解决方案是在字典中命名为闭包,但即使这样也有点代码味道。 – Sulthan