I'm designing a macOS app with SwiftUI. I need to modify an EnvironmentObject whose value is calculated from a State variable. To do this, I tried to call a method that does the calculation and updates the EnvironmentObject, but the method appears to fall into an infinite loop that causes the app to stop responding.
Can someone explain what's going on? And, how do I achieve the same ends without having this problem?
I wrote this code to demonstrate what I mean:
final class Input: ObservableObject {
@Published var bar = 0
}
struct ContentView: View {
@State var foo = 0
@EnvironmentObject var input: Input
func increment(code: Int) {
print("function called")
switch code {
case 0:
input.bar -= 1
case 1:
input.bar += 1
default:
print("unknown")
}
print("\(input.bar)")
}
var body: some View {
increment(code: foo)
return Text("Hello world!") // In reality this is code that modifies foo
}
}
When this code is run, the console prints "function called" in an infinite loop, and also prints continuously decreasing values of input.bar. From my experimentation, I found that:
Replacing
input.barwith some other code (e.g. a simpleprintcommand) does not cause an infinite loop.With this same code, setting
footo2(thus giving thedefaultcase) also doesn't cause an infinite loop.foodoesn't need to be aStatevar, the app crashes even if it's a simple variable.