CFReadStreamSetClient
在其初始化程序中有一个C函数回调函数(CFReadStreamClientCallBack
),
CFReadStreamClientCallback
看起来像这样:
typealias CFReadStreamClientCallBack = (CFReadStream!,
CFStreamEventType, UnsafeMutablePointer<Void>) -> Void
我有一个尝试处理CFReadStreamClientCallBack
C函数回调的方法:
func callback(stream: CFReadStreamRef,
eventType: CFStreamEventType,
inClientInfo: UnsafeMutablePointer<Void>) {
}
但是当我尝试按如下方式在CFReadStreamCallback
中设置回调时,它不会编译。
CFReadStreamSetClient(stream, registeredEvents, callback, clientContextPtr)
我知道使用Swift 2.0有一种方法可以使用带有C函数回调的Swift闭包,但我似乎无法让它工作。有谁知道在这种情况下如何做到这一点?
答案 0 :(得分:4)
你可以创建一个闭包来完成你在函数中所做的事情:
CFReadStreamSetClient(stream, registeredEvents, { readStream, event, data -> Void in
// Do stuff here.
}, clientContextPtr)
另请注意,C功能块不具备上下文,因此您无法访问自身或来自块外部的任何其他变量。 如果这不起作用,您可以在问题中包含编译器错误吗?
答案 1 :(得分:3)
Swift 2.0:
给定一个带函数指针和上下文的函数:
void c_func_with_callback(void *context, void (*callback)(void *context))
从Swift中调用它很容易,但它无法访问封闭类的变量:
c_func_with_callback(nil) { context in
print("Callback in Swift!") // OK
self.xxx // error
}
如果您需要访问块之外的变量,可以使用上下文存储指向该类的指针:
class MyClass {
func hello() {
print("MyClass.hello()")
}
func classMethodAsCallback() {
let context = unsafeBitCast(self, UnsafeMutablePointer<Void>.self)
c_func_with_callback(context) { context in
let caller = unsafeBitCast(context, MyClass.self)
caller.hello()
}
}
}
let myClass = MyClass()
myClass.classMethodAsCallback()
甚至可以将ANY闭包用作回调:
class MyClass {
typealias Closure = ()->()
func anySwiftClosureAsCallback(closure: Closure) {
var c = closure
// closure won't fit in a pointer, so take it's address first
let context = withUnsafePointer(&c) {
//(ptr: UnsafePointer<Closure>) -> UnsafeMutablePointer<Void> in
ptr in
return unsafeBitCast(ptr, UnsafeMutablePointer<Void>.self)
}
c_func_with_callback(context) { context in
let ptr = unsafeBitCast(context, UnsafePointer<Closure>.self)
let closure = ptr.memory // dereference the address
closure()
}
}
}
let myClass = MyClass()
myClass.anySwiftClosureAsCallback {
print("Swift closure called")
}