【问题标题】:Swift perform selector with inout argumentSwift 使用 inout 参数执行选择器
【发布时间】:2020-09-06 20:01:13
【问题描述】:

我有一个我想从 swift 调用的 objc 方法,但该方法存在于第三方框架中,在运行时可能存在也可能不存在。 我想做的是动态调用它,所以我正在研究使用选择器与之交互。

方法签名在 ObjC 中是这样的

- (NSString * _Nullable)buildData:(NSError * _Nullable __autoreleasing * _Nullable)error;

删除可以为空的注释,这是 ObjC 永远拥有的沼泽标准“返回事物或错误”模式。

- (NSString*)buildData:(NSError*)error;

如果 swift 可以在编译时加载它,那么它会很高兴地转换为

func buildData() throws -> String

但是,我想动态调用它。我已经知道我可以做到这一点:

let _target:NSObject = // obtain a reference to the underlying value

var error: NSError? = nil
_target.perform(NSSelectorFromString("buildData:"), with: &error)

问题是,我无法传递对执行选择器方法的引用。 XCode 给了我一个编译错误

'&' 与 'Any?' 类型的非 inout 参数一起使用

所以我的问题是,如何使用选择器调用此方法?

【问题讨论】:

标签: objective-c swift selector


【解决方案1】:

试试这个:

var error: NSError? = nil
let _target: NSObject = // obtain a reference to the underlying value

withUnsafeMutablePointer(to: &error) {
    let selector: Selector = NSSelectorFromString("buildData:")
    let methodIMP: IMP! = _target.method(for: selector)
    unsafeBitCast(methodIMP,to:(@convention(c)(Any?,Selector,OpaquePointer)->Void).self)(_target,selector,OpaquePointer($0))
}

在我的回答 here 中使用 convention(c) 在 Swift 中调用选择器的更多信息

【讨论】:

  • 它似乎在我的初始测试中有效。非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-29
  • 1970-01-01
  • 1970-01-01
  • 2015-01-01
  • 2017-06-16
  • 1970-01-01
相关资源
最近更新 更多