iOS 27 regression: Objects whose properties are bound to items displayed in a Menu are not correctly deallocated

A regression has been introduced with SwiftUI Menu in iOS 27 betas (still present in beta 6).

This regression prevents objects whose properties are bound to contained Menu items from being correctly deallocated.

In the example below, Player was immediately deallocated when the surrounding ModalView was dismissed on iOS 26 (or below):

import Observation
import SwiftUI

@Observable
final class Player {
    var playbackSpeed: Double = 1
}

struct ModalView: View {
    @State private var player = Player()

    var body: some View {
        Menu {
            Picker(selection: $player.playbackSpeed) {
                ForEach([0.5, 1, 1.5, 2], id: \.self) { speed in
                    Text("\(speed, specifier: "%g×")").tag(speed)
                }
            } label: {
                Text("Speed")
            }
            .pickerStyle(.inline)
        } label: {
            Text("Menu")
        }
    }
}

This is not the case anymore on iOS 27 beta. The Player instance is not deallocated anymore.

A dedicated feedback (FB24486991) has been opened.

Answered by DTS Engineer in 904117022

Hello @defagos

Thank you for reporting the issue and providing a clear example.

I made sure your report was seen by the relevant engineering team, it looks like they confirmed the issue is resolved in iOS 27 as well.

As a workaround for iOS 26 builds, use runtime version checks with #available in a condition that only runs in iOS 26, and try using a proxy @State property as the binding instead of binding directly to the @Observable object's property, then syncing changes back with .onChange.

if #available(iOS 27, *) {
    // iOS 27-specific code
} else {
    // Workaround code
}

Adjust the conditional statement to one that makes sense for your implementation.

 Travis

Hello @defagos

Thank you for reporting the issue and providing a clear example.

I made sure your report was seen by the relevant engineering team, it looks like they confirmed the issue is resolved in iOS 27 as well.

As a workaround for iOS 26 builds, use runtime version checks with #available in a condition that only runs in iOS 26, and try using a proxy @State property as the binding instead of binding directly to the @Observable object's property, then syncing changes back with .onChange.

if #available(iOS 27, *) {
    // iOS 27-specific code
} else {
    // Workaround code
}

Adjust the conditional statement to one that makes sense for your implementation.

 Travis

Hi Travis,

Thank you very much for your answer and for considering this feedback.

A few remarks:

  • The issue affects iOS 27, not iOS 26. On iOS 26 no specific code is needed.
  • The issue still affects iOS 27 beta 8. You might have access to internal builds which resolved this issue but the latest developer beta we have access to is still affected.
  • The workaround you propose is helpful, thanks. Note you also usually need a way to observe object property changes as well (e.g. via onReceive on a Published property publisher, if you are still using ObservableObject) so that the local @State can be updated accordingly. Otherwise changes made outside the menu will not be correctly reflected in the menu UI.

Thank you for the clarification @defagos

I have shared this along with your report and the team is aware of the issue.

Since the resolution might require changes to the framework you are using, updates for this issue will be provided from that team directly though Feedback Assistant. Check there for updates.

Use this thread to test across versions and update us if the issue is still occurring or resolved in some way.

If others run into this issue, I encourage they use the workaround ideas we are suggesting.

Thank you,

 Travis

Perfect, thank you very much for your help!

iOS 27 regression: Objects whose properties are bound to items displayed in a Menu are not correctly deallocated
 
 
Q