在"ViewController.swift"中我创建了这个回调:
func callback(cf:CFNotificationCenter!,
ump:UnsafeMutablePointer<Void>,
cfs:CFString!,
up:UnsafePointer<Void>,
cfd:CFDictionary!) -> Void {
}
Run Code Online (Sandbox Code Playgroud)
使用此观察者:
CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(),
nil,
self.callback,
"myMESSage",
nil,
CFNotificationSuspensionBehavior.DeliverImmediately)
Run Code Online (Sandbox Code Playgroud)
导致此编译器错误:
"AC函数指针只能通过对'func'或文字闭包的引用形成"
Mar*_*n R 35
回调是指向C函数的指针,在Swift中,您只能传递全局函数或闭包(不捕获任何状态),但不能传递实例方法.
所以这确实有效:
CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(),
nil,
{ (_, observer, name, _, _) in
print("received notification: \(name)")
},
"myMessage",
nil,
.DeliverImmediately)
Run Code Online (Sandbox Code Playgroud)
但由于闭包无法捕获上下文,因此您无法直接引用self其属性和实例方法.例如,您无法添加
self.label.stringValue = "got it"
// error: a C function pointer cannot be formed from a closure that captures context
Run Code Online (Sandbox Code Playgroud)
在闭包内部,在通知到达时更新UI.
有一个解决方案,但由于Swift严格的类型系统,它有点复杂.与Swift 2 - UnsafeMutablePointer <Void>中的对象类似,您可以将指针转换
self为void指针,将其作为observer参数传递给注册,并将其转换回回调中的对象指针.
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(),
observer,
{ (_, observer, name, _, _) -> 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)
},
"myMessage",
nil,
.DeliverImmediately)
}
// ...
}
Run Code Online (Sandbox Code Playgroud)
闭包充当实例方法的"蹦床".
指针是未保留的引用,因此必须确保在取消分配对象之前删除观察者.
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(),
observer,
{ (_, observer, name, _, _) -> 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,
nil,
.deliverImmediately)
}
// ...
}
Run Code Online (Sandbox Code Playgroud)
有关对象指针和C指针之间"桥接"的更多信息,另请参见如何将self转换为UnsafeMutablePointer <Void>键入swift.
| 归档时间: |
|
| 查看次数: |
10709 次 |
| 最近记录: |