I am learning memory and ARC since a while and managed to use the Leaks instrument more often in order to produce quality code. Having that said, please consider my lack of experience in this zone.
Problem: I built a parent view A that presents a view B.
B contains a login form built using a TextField
, a SecureField
and a Button
. I also have a @FocusState private var isFocused: Bool
property that helps me hide the keyboard in order to bypass the "AttributeGraph: cycle detected" console error that shows up once I disable the textfield on button press having the keyboard on screen. (Get `AttributeGraph: cycle detected` error when changing disabled state of text field)
I noticed that when I use the @FocusState
property, once I dismiss B, the Leaks instrument detects two "Malloc 32 Bytes" leaks just like in the picture below.
If I don’t use the @FocusState
property, the leaks will no longer show up. Am I doing something wrong or is this some kind of bug / false positive from Swift?
This view is partially extracted from my file so it doesn’t have all it’s properties and methods here.
struct AuthenticationLoginView: View {
@StateObject var viewModel = AuthenticationLoginViewModel()
@FocusState private var isFocused: Bool
var body: some View {
VStack {
TextField(text: $viewModel.username) {
Text("placeholder.")
}
.tag(AuthenticationLoginField.username)
.textInputAutocapitalization(.never)
.focused($isFocused)
.disabled(viewModel.isLoggingIn)
SecureField(text: $viewModel.password) {
Text("Password")
}
// .focused($isFocused)
.disabled(viewModel.isLoggingIn)
.tag(AuthenticationLoginField.password)
}
}
}
2
Answers
Without more code it is hard to tell what else you are doing that may have caused the leak.
My gut is that having a single focus boolean when you have two edit fields is an anti-pattern compared to Apple’s way. When something is evolving like SwiftUI, try to follow their example styles more closely. Use a boolean only when there’s just one focusable field.
This similar Hacking with Swift sample shows using an optional and changing the focus as fields submitted.
I found this problem. In my case, it caused a massive retain loop which fed all the way back to coordinator with a bunch of objects.
Just showing a TextField with focus (either the bool way, or the enum way) caused a retain.
My fix was to use the introspect library and just set first responder manually