Search code examples
swiftcocoa

Swift 5.5: How to properly access the notification object inside the notification handler when its object has to be processed on the main queue?


This minimal example

class ViewController : NSViewController {
    override func loadView() {
        NotificationCenter.default.addObserver(forName: NSView.frameDidChangeNotification, object: view, queue: .main) { [self] n in
            DispatchQueue.main.async {
                self.resizeSubviews(animate: false, sender: n.object) // <- warning here
            }
        }
    }

    func resizeSubviews(animate: Bool, sender: Any?) {
    }
}

causes the warning:

Capture of 'n' with non-sendable type 'Notification' in a `@Sendable` closure

Although the Main dispatch queue is already asked for when adding the observer I have to wrap the resizeSubviews call in an DispatchQueue.main.async block.

How do I properly access n inside the notification handler?


Solution

  • The notification is a non-sendable type, don't use it inside the closure. n.object is of type Any?, cast it to NSView.

    NotificationCenter.default.addObserver(forName: NSView.frameDidChangeNotification, object: view, queue: .main) { [self] n in
        guard let sender = n.object as? NSView else { return }
        DispatchQueue.main.async {
            self.resizeSubviews(animate: false, sender: sender)
        }
    }