将 IMP 转换为 Swift 中的函数

Convert IMP to a func in Swift

我正尝试在我的代码中这样做:

typealias voidIMP = (NSObject, Selector, String) -> ()

let string = NSMutableString()
var selector = Selector("setString:")

var setStringMethod: IMP = string.methodForSelector("setString:")
let callBack =  Unmanaged.fromOpaque(setStringMethod).takeUnretainedValue() as AnyObject as! voidIMP

for _ in 0..<1000 {
   callBack(string, selector, "stuff")
} 

但是应用程序在第 5 行崩溃并出现 EXC_BAD_INSTRUCTION 错误。

如何在 Swift 中使用 IMP?我试图将 IMP(setStringMethod) 转换为 func,但没有成功。 Objective-C 版本工作正常。

两种方法可以实现这一点。第一个,相当不安全,使用位转换并基于您的示例:

typealias setStringIMP = @convention(c) (NSObject, Selector, String) -> Void

let string = NSMutableString()
let selector = Selector("setString:")

let callback = unsafeBitCast(string.methodForSelector(selector), setStringIMP.self)

callback(string, selector, "stuff")

请注意 typealias 中的 @convention(c) – 这会告诉编译器您正在对 C 函数进行类型别名。


如果您只想使用一个方法作为回调,但是,因为 方法是第一个-class 函数,您可以执行以下操作:

let string = NSMutableString()
let callback = string.setString

callback("stuff")

这比使用不安全的位转换要安全得多。