1

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?

enter image description here

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)
            }
    }
}

robertsan
  • 1,501
  • 3
  • 13
  • 25

1 Answers1

0

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.

    @FocusState private var focusedField: FocusedField?
    @State private var username = "Anonymous"
    @State private var password = "sekrit"

    var body: some View {
        VStack {
            TextField("Enter your username", text: $username)
                .focused($focusedField, equals: .username)

            SecureField("Enter your password", text: $password)
                .focused($focusedField, equals: .password)
        }
        .onSubmit {
            if focusedField == .username {
                focusedField = .password
            } else {
                focusedField = nil
            }
        }
Andy Dent
  • 16,995
  • 6
  • 83
  • 111
  • 1
    Just discovered that also Apple's example leaks memory. Tried both Apple's example and the one from Hacking with Swift in a new project. Maybe it's going to be fixed in a future release. Currently using Xcode 13.4. – robertsan May 24 '22 at 08:49
  • Log a Radar on it. Also, is it a real "leak" every time you show that screen, or just an allocation of two blocks that aren't cleaned up until app exit? There are a lot of false positives in leak monitoring. – Andy Dent May 25 '22 at 09:21