In "ViewController.swift" I am creating this callback:
func callback(cf:CFNotificationCenter!,
ump:UnsafeMutablePointer<Void>,
cfs:CFString!,
up:UnsafePointer<Void>,
cfd:CFDictionary!) -> Void {
}
Using this observer:
CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(),
nil,
self.callback,
"myMESSage",
nil,
CFNotificationSuspensionBehavior.DeliverImmediately)
Results in this compiler error:
"A C function pointer can only be formed from a reference to a 'func' or a literal closure"
The callback is a pointer to a C function, and in Swift you can pass only a global function or a closure (which does not capture any state), but not an instance method.
So this does work:
But since the closure cannot capture context, you have no direct reference to
self
and its properties and instance methods. For example, you cannot addinside the closure to update the UI when a notification arrived.
There is a solution, but it is a little bit complicated due to Swift's strict type system. Similarly as in Swift 2 - UnsafeMutablePointer<Void> to object, you can convert the pointer to
self
to a void pointer, pass that as theobserver
parameter to the registration, and convert it back to an object pointer in the callback.The closure acts as a "trampoline" to the instance method.
The pointer is an unretained reference, therefore you must ensure that the observer is removed before the object is deallocated.
Update for Swift 3:
See also How to cast self to UnsafeMutablePointer<Void> type in swift for more information about the "bridging" between object pointers and C pointers.
In my case the function I wanted to call from my closure was in the AppDelegate. So I was able to use a delegate to call the function from the closure without using self. Whether this is a good idea or not is something that someone with more experience will have to comment on.