Swift:沉默“不可发送的通知?无法跨越参与者边界”警告

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

问题

我有一个 Mac 应用程序需要在 Mac 睡眠时执行操作。为此,我使用这种“现代”方法来监听通知:

@MainActor
final class AppController: NSObject, ObservableObject
{
   var sleepTask: Task<Void, Never>? = nil

   override init()
   {
       sleepTask = Task { [weak self] in
          for await _ in NSWorkspace.shared.notificationCenter.notifications(named: NSWorkspace.willSleepNotification) 
          {
              Task { @MainActor in
                 self?.doSomething()
              }
          }
       }
   }
}

Xcode 15 beta 8 在

for/await
调用中引入了新警告:

Non-sendable type 'Notification?' returned by implicitly asynchronous call to nonisolated function cannot cross actor boundary
1. Generic enum 'Optional' does not conform to the 'Sendable' protocol (Swift.Optional)

但是我根本没有使用通知对象;它没有跨越演员边界。

问题:

如何消除此警告? (除了强迫

Optional
遵守
@unchecked Sendable
)。

swift actor swift-concurrency
1个回答
0
投票

你说:

如何消除此警告? (除了强迫

Optional
遵守
@unchecked Sendable
)。

您可以:

  1. 您可以将

    Notification
    声明为
    Sendable
    。例如,

    extension Notification: @unchecked Sendable { }
    

    这令人不安。感觉这个

    struct
    应该是
    Sendable
    ,但不清楚为什么不是。我不知道他们是否还没有抽出时间来做这件事,或者内部是否发生了一些事情阻止他们这样做。

  2. 您还可以更改序列以产生

    Notification
    之外的其他内容:

    sleepTask = Task { [weak self] in
        let sequence = NSWorkspace
            .shared
            .notificationCenter
            .notifications(named: NSWorkspace.willSleepNotification)
            .map { _ in () }
    
        for await _ in sequence {
            self?.doSomething()
        }
    }
    
© www.soinside.com 2019 - 2024. All rights reserved.