在“ViewController.
swift”中,我创建了这个回调:
func callback(cf:CFNotificationCenter!,ump:UnsafeMutablePointer<Void>,cfs:CFString!,up:UnsafePointer<Void>,cfd:CFDictionary!) -> Void {
}
使用这个观察者:
CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(),nil,self.callback,"myMESSage",CFNotificationSuspensionBehavior.DeliverImmediately)
导致此编译器出现错误:
“C函数指针只能通过引用”func“或者是文字闭包来形成”
@H_
403_11@
回调是指向C
函数的指针,在Swift中可以通过
只有一个全局
函数或闭包(不捕获任何状态),
但不是一个实例
方法.
所以这样做是有效的:
CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(),{ (_,observer,name,_,_) in
print("received notification: \(name)")
},"myMessage",.DeliverImmediately)
但是由于闭包无法捕获上下文,因此您没有直接引用自身及其属性和实例方法.
例如,您不能添加
self.label.stringValue = "got it"
// error: a C function pointer cannot be formed from a closure that captures context
在通知到达时,关闭内部更新UI.
有一个解决方案,但它有点复杂
Swift的严格型系统.
类似于Swift 2 – UnsafeMutablePointer<Void> to object,您可以将指针转换为
self到void指针,将其作为观察器参数传递
到注册,并将其转换回到一个对象指针
回调.
class YourClass {
func callback(name : String) {
print("received notification: \(name)")
}
func registerObserver() {
// Void pointer to `self`:
let observer = UnsafePointer<Void>(Unmanaged.passUnretained(self).toOpaque())
CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(),_) -> Void in
// Extract pointer to `self` from void pointer:
let mySelf = Unmanaged<YourClass>.fromOpaque(
COpaquePointer(observer)).takeUnretainedValue()
// Call instance method:
mySelf.callback(name as String)
},.DeliverImmediately)
}
// ...
}
封闭作为实例方法的“蹦床”.
指针是一个无法引用的参考,因此您必须确保
在对象被释放之前观察者被移除.
Swift 3的更新:
class YourClass {
func callback(_ name : String) {
print("received notification: \(name)")
}
func registerObserver() {
// Void pointer to `self`:
let observer = UnsafeRawPointer(Unmanaged.passUnretained(self).toOpaque())
CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(),_) -> Void in
if let observer = observer,let name = name {
// Extract pointer to `self` from void pointer:
let mySelf = Unmanaged<YourClass>.fromOpaque(observer).takeUnretainedValue()
// Call instance method:
mySelf.callback(name.rawValue as String)
}
},"myMessage" as CFString,.deliverImmediately)
}
// ...
}
参见How to cast self to UnsafeMutablePointer<Void> type in swift了解更多信息关于对象指针和C指针之间的“桥接”.