swiftfoundationnotificationcenter

Passing closure in userInfo to NotificationCenter, getting cryptic messages from compiler at runtime


I'm trying to pass a closure in userInfo through NotificationCenter. The closures works as expected but I'm getting weird messages that I do not understand in runtime. What is the cause of this message?

The message is:

0x000000010292b350 [ProjectName]`partial apply forwarder for reabstraction thunk helper from @escaping @callee_guaranteed () -> (@out ()) to @escaping @callee_guaranteed () -> () at <compiler-generated>

This is how I post the notification.

let closure: (() -> Void) = {
        print("TEST")
    }
        
NotificationCenter.default.post(name: .test, 
    object: nil, 
    userInfo: ["closure" : closure ])

This is how I consume the notificaiton:

@objc private func test(_ notification: Notification) {
    let closure = notification.userInfo?["closure"] as? (() -> Void)
    closure?()
}

I'm using Swift 5.


Solution

  • Unfortunately I can't reproduce the error, but I would suggest wrapping the closure in a wrapper class. Things that need to round-trip into and out of Cocoa do better when they are NSObjects:

    class Wrapper : NSObject {
        let closure : () -> Void
        init(closure: @escaping () -> Void) {
            self.closure = closure
        }
    }
    
    class ViewController: UIViewController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
            let closure: (() -> Void) = {
                print("TEST")
            }
            let wrapper = Wrapper(closure: closure)
            let test = Notification.Name("Test")
            NotificationCenter.default.addObserver(self,
                selector: #selector(testing), name: test, object: nil)
            NotificationCenter.default.post(name: test,
                object: nil, userInfo: ["wrapper" : wrapper ])
        }
    
        @objc private func testing(_ notification: Notification) {
            let wrapper = notification.userInfo?["wrapper"] as? Wrapper
            wrapper?.closure()
        }
    }