After updating to Xcode 14.0 beta 5 (14A5294e) I'm seeing runtime warnings on iOS when simply changing a published variable from within a button's action.
I'm wondering if this is a false positive on the warning or if there is a new pattern we're supposed to be following here.
This appears to only happen on iOS. The same reproducing code does not output that warning while running on macOS.
Here's a contrived yet complete example that reproduces it on an iPhone 13 Pro simulator while running Xcode 14 beta 5. Does not reproduce the warning when running on Ventura.
class ViewModel: ObservableObject {
@Published var sheetVM: SheetVM?
func showSheet() {
sheetVM = SheetVM(delegate: self)
}
}
extension ViewModel: SheetDelegate {
func close() {
sheetVM = nil
}
}
class SheetVM: ObservableObject, Identifiable {
weak var delegate: SheetDelegate?
init(delegate: SheetDelegate) {
self.delegate = delegate
}
func close() {
delegate?.close()
}
}
protocol SheetDelegate: AnyObject {
func close()
}
struct ContentView: View {
@ObservedObject
var viewModel: ViewModel
var body: some View {
VStack {
Button {
viewModel.showSheet()
} label: {
Text("Show Sheet")
}
}
.padding()
.sheet(item: $viewModel.sheetVM) { sheetVM in
SheetView(sheetVM: sheetVM)
}
}
}
struct SheetView: View {
let sheetVM: SheetVM
var body: some View {
NavigationView {
Text("Sheet View")
.toolbar {
ToolbarItem(placement: .automatic) {
Button {
sheetVM.close()
} label: {
Text("Done")
.fontWeight(.semibold)
}
}
}
}
}
}
Here's the warning and trace while tapping done on the sheet:
warning run: Publishing changes from within view updates is not allowed, this will cause undefined behavior.
Thread 1
#0 0x0000000000000000 in ___lldb_unnamed_symbol155969 ()
#1 0x0000000000000000 in ___lldb_unnamed_symbol155968 ()
#2 0x0000000000000000 in ___lldb_unnamed_symbol155988 ()
#3 0x0000000000000000 in ___lldb_unnamed_symbol180158 ()
#4 0x0000000000000000 in ObservableObjectPublisher.Inner.send() ()
#5 0x0000000000000000 in ObservableObjectPublisher.send() ()
#6 0x0000000000000000 in PublishedSubject.send(_:) ()
#7 0x0000000000000000 in specialized static Published.subscript.setter ()
#8 0x0000000000000000 in static Published.subscript.setter ()
#9 0x0000000000000000 in ViewModel.sheetVM.setter ()
#10 0x0000000000000000 in key path setter for ViewModel.sheetVM : ViewModel ()
#11 0x0000000000000000 in NonmutatingWritebackBuffer.__deallocating_deinit ()
#12 0x0000000000000000 in _swift_release_dealloc ()