Deinit not called in certain scenarios with for await loop

I just ran into this, and wanted to share a recipe that works for me. I have a SwiftUI View with the associated ViewModel that’s owned by the view as a StateObject. I want the viewModel to be able to react to a bunch of notifications with the modern async API and long-running AsyncSequences, and for everything to be deallocated correctly when the view ends. I don’t want to code anything by hand and want things to happen automatically with the highest-level code possible.

Here’s what I came up with, that seems to work.

class MyViewModel: ObservableObject {
  deinit {
    // just for observability that it’s released correctly
    print("MyViewModel deinit")
  }
}

struct MyView: View {
  @StateObject private var myViewModel: MyViewModel()

  var body: some View {
    WhateverView()
    .task {
      for await _ in NotificationCenter.default.notifications(named: .notification1) {
        myViewModel.doSomething1()
      }
    }
    .task {
      for await note in NotificationCenter.default.notifications(named: .notification2) {
        if let receivedObject = note.object as? SomeObject {
          await myViewModel.ingestObject(receivedObject)
        }
      }
    }
  }
}

This seems to work correctly. I can start as many long-running listener tasks as I want, and they are all torn down and the view model object is deallocated when the view is closed which automatically cancels the tasks.