UPDATE:
I believe I found what was consuming memory as I updated the UI...
I have a View that contains a Text object that displays the number of sequences read from a file of DNA sequences as well as a List of sequence names. These files are typically very large because each individual sequence can consist of thousands to millions of nucleotides. However, the number of sequences in a file can be relatively small and manageable. My goal is to read these files and display the number of sequences as well as a list of the sequence names and statistics about each sequence (but not all the nucleotides because that is too much data).
I update the Text object periodically by setting a property that I call sequenceCount. This property is a member of the following class:
class ObservableSequences: ObservableObject {
@Published var sequenceCount: String? = "0"
@Published var sequenceData: [SequenceData] = []
}
sequenceCount contains the number of sequences read from the file while sequenceData contains information about each sequence in the file. I periodically update sequenceCount from a background thread that is reading the file. I do this to keep the user informed about the progress being made processing the file.
I have a master/detail UI. My master View is declared as follows:
struct MasterView: View {
@ObservedObject public var observableSequences = ObservableSequences()
var body: some View {
VStack {
Text("Number of Lines: " + observableSequences.sequenceCount!)
List(self.observableSequences.sequenceData, id: \.self) {sequenceData in
NavigationLink(destination: DetailView(sequence: sequenceData.sequence)) {
Text(sequenceData.sequence)
}.background(Color.red)
}
}
}
}
For reasons that I don't remember, I had originally written this View as follows:
struct MasterView: View {
@ObservedObject public var observableSequences = ObservableSequences()
var body: some View {
VStack {
Text("Number of Lines: " + observableSequences.sequenceCount!)
List(self.observableSequences.sequenceData, id: \.self) {sequenceData in
NavigationLink(destination: DetailView(sequence: sequenceData.sequence)) {
Text(sequenceData.sequence)
}.background(Color.red)
}.id(UUID()) <------------------------NOTE THE USE OF .id
}
}
}
When I removed .id(UUID()), memory no longer grew out of control and remained stable.
It seems that each time I updated sequenceCount, the UI would be recreated (as I would expect). And each List that is created got a new .id. My guess (and it is only a guess) is that each new List was being retained in memory. Without the unique id, a new List is either not created or the previous List is being disposed of and not retained in memory.
In any case, my code is now behaving nicely even though I am reading exceptionally large files.
Topic:
App & System Services
SubTopic:
General
Tags: