在IMP中将IMP转换为func

时间:2015-12-02 17:22:59

标签: ios swift objective-c-runtime

我试图在我的代码中执行此操作:

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版本运行正常。

1 个答案:

答案 0 :(得分:1)

两种方式来实现这一目标。第一个,相当不安全,使用比特铸造,并基于你的例子:

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")

请注意@convention(c)中的typealias - 这告诉编译器您正在键入C函数。

如果您只想将方法用作回调,但由于方法是一流功能,您可以执行以下操作:

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

callback("stuff")

这比使用不安全的位铸造更安全。