0

Here is a very simple code example that reproduces a memory leak when deleting an item in SwiftUI List. This is reproducible on iOS 15 and iOS 16 (at least).

Item's are never deallocated even if they are deleted from the list.

import SwiftUI

class Item: Identifiable {
    let id: String

    init(id: String) {
        self.id = id
    }

    deinit {
        print("deinit")
    }
}

struct ContentView: View {
    @State private var data = [
        Item(id: "1"),
        Item(id: "2"),
        Item(id: "3")
    ]

    var body: some View {
        List {
            ForEach(data) { Text($0.id) }
                .onDelete { indexes in
                    data.remove(at: indexes.first!)
                }
        }
    }
}

This seems like a very basic example so I am wondering if anyone has noticed this or has a workaround?

LazyVStack and LazyVGrid exhibit the same behaviour.

josip04
  • 224
  • 3
  • 13

1 Answers1

-2

The memory leak is because you used a class instead of a struct for your model, SwiftUI hangs onto things it needs for use in its diffing algorithm, since usually these things are values there is no need to worry about memory leaks, however it is a problem if you use classes/objects as you have experienced.

SwiftUI is designed to take advantage of value semantics. This means when there is a change to the Item, it is also a change to the data array. SwiftUI tracks what @State getters are called in body, since data is called from body it knows that when the @State setter is called it needs to call body to get the new version of the Views. So a change to item, is a change to the data array, which is a change to the @State and then SwiftUI works correctly. However, for this to work Item must a value type, i.e. a struct, not a class.

struct Item: Identifiable {
    let id: String

    init(id: String) {
        self.id = id
    }
}
malhal
  • 26,330
  • 7
  • 115
  • 133
  • This does not provide an answer to the question. To critique or request clarification from an author, leave a comment below their post. - [From Review](/review/low-quality-posts/33960912) – ilias-sp Mar 03 '23 at 12:35
  • @ilias-sp it now answers the question and even provides a work around they asked for. – malhal Mar 03 '23 at 15:16