首页 > 解决方案 > 将 userInfo 中的闭包传递给 NotificationCenter,在运行时从编译器获取神秘消息

问题描述

我正在尝试通过 NotificationCenter 在 userInfo 中传递一个闭包。闭包按预期工作,但我收到了一些我在运行时不理解的奇怪消息。此消息的原因是什么?

消息是:

0x000000010292b350 [ProjectName]`部分应用转发器,用于从@escaping @callee_guaranteed () -> (@out ()) 到 @escaping @callee_guaranteed () -> () 在 <compiler-generated>

这就是我发布通知的方式。

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

这就是我使用通知的方式:

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

我正在使用 Swift 5。

标签: swiftfoundationnotificationcenter

解决方案


不幸的是,我无法重现该错误,但我建议将闭包包装在包装类中。当它们是 NSObjects 时,需要往返进出 Cocoa 的东西会做得更好:

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()
    }
}


推荐阅读