我试图在我的代码中执行此操作:
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版本运行正常。
答案 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")
这比使用不安全的位铸造更安全。