.onReceive NSWindow.willCloseNotification 为应用程序中的每个窗口调用?

问题描述 投票:0回答:1

我正在用 SwiftUI 编写一个多平台应用程序。

它可以处理 3 种不同类型的窗口,以及用户想要打开的任意数量的窗口实例。

当用户关闭窗口时,我需要进行一些清理,因此我将以下内容添加到视图层次结构中的顶级视图中(在本例中为

NavigationStack

    .onReceive(NotificationCenter.default.publisher(for: NSWindow.willCloseNotification)) { newValue in
        // Do cleanup
    }

我的期望是,当包含此特定 View 对象的特定窗口关闭时,将调用我的

.onReceive
处理程序的闭包。

如果你在AppKit中查找

NSWindow.willCloseNotification
,它表示它将通知发送到即将关闭的特定窗口对象。

但是,似乎在 SwiftUI 中,当任何窗口即将关闭时,它都会在每个窗口上调用。

为什么会这样?当 NSWindow 的特定实例即将关闭时,是否有一些技巧可以获取通知?

swift macos swiftui nsnotificationcenter
1个回答
0
投票

如果你在AppKit中查找

NSWindow.willCloseNotification
,它表示它将通知发送到即将关闭的特定窗口对象。

我认为这里可能对文档试图表达的内容存在误解。来自文档

通知对象是即将关闭的

NSWindow
对象。此通知不包含
userInfo
字典。

“通知对象”这里指的是

Notification.object
,它是一个通用属性(一般,不是
<T>
意义上的),描述与通知相关的对象。有些通知是全局的,与特定对象无关(在这种情况下,它可以是
nil
),而其他通知则指示与特定对象相关的更改,在这种情况下,这将被设置。

在这种特定情况下,为

object
收到的
Notification
NSWindow.willCloseNotification
属性被记录为将要关闭的窗口,以便您可以区分可以关闭的窗口。

不过,

Notification.object
不仅仅是接收通知时的相关信息:您可以使用特定对象作为订阅通知时接收通知的 filter
NotificationCenter.addObserver(forName:object:queue:using:)
NotificationCenter.addObserver(_:selector:name:object:)
都允许您传递
object
参数,以便仅传递
.object
与给定对象匹配的通知 - 即,如果您只关心接收
NSWindow.willCloseNotification
一个特定窗口对象,您可以预先传递它,只有当
.object
匹配时才会发送通知。

至关重要的是,

NotificationCenter.publisher(for:object:)
also 允许您传入
object
进行过滤——它恰好默认为
nil
(这意味着不应用过滤器)。订阅没有对象的通知的最终效果是,每个订阅的窗口都将收到关闭的any窗口的通知;即,正是您所看到的。

如果您希望每个视图层次结构在其包含窗口即将关闭时得到通知,则需要提供对包含

NSWindow
publisher(for:object:)
的引用。 (我不认为有直接的方法可以访问 SwiftUI 中包含的
NSWindow
,因此您可能需要在创建顶级视图时传递引用。)

© www.soinside.com 2019 - 2024. All rights reserved.