I have this APIRepresentative class as a singleton EnvironmentObject in my SwiftUI app. The class has @Published var that holds all InsightData structs by ID.
Even in a view that has no dependencies on insightData, repeatedly calling the getInsightData function causes memory usage in my app to rise by about 200Kb or so each time. Over the lifetime of my app, this will cause memory usage to balloon to several gigabytes.
Here's the kicker: The memory leak vanishes when I remove the @Published modifier for insightData. I can then call my function as much as I like, with no increase in memory usage. Any idea why that is the case? I would very much like to keep the @Published property.
import Foundation
import Combine
final class APIRepresentative: ObservableObject {
private static let baseURLString = "https://apptelemetry.io/api/v1/"
@Published var insightData: [UUID: InsightDataTransferObject] = [:]
// More published properties
// ...
}
extension APIRepresentative {
func getInsightData(for insight: Insight, in insightGroup: InsightGroup, in app: TelemetryApp, callback: ((Result<InsightDataTransferObject, TransferError>) -> ())? = nil) {
let timeWindowEndDate = timeWindowEnd ?? Date()
let timeWindowBeginDate = timeWindowBeginning ?? timeWindowEndDate.addingTimeInterval(-60 * 60 * 24 * 30)
let url = urlForPath("apps", app.id.uuidString, "insightgroups", insightGroup.id.uuidString, "insights",
insight.id.uuidString,
Formatter.iso8601noFS.string(from: timeWindowBeginDate),
Formatter.iso8601noFS.string(from: timeWindowEndDate)
)
let request = self.authenticatedURLRequest(for: url, httpMethod: "GET")
URLSession.shared.dataTask(with: request) { data, response, error in
if let data = data {
let decoded = try! JSONDecoder.telemetryDecoder.decode(InsightDataTransferObject.self, from: data)
DispatchQueue.main.async { [weak self] in
guard let self = self else {
print("Self is gone")
return
}
var newInsightData = self.insightData
newInsightData[decoded.id] = decoded
self.insightData = newInsightData
}
}
}.resume()
}
}
// more retrieval functions for the other published properties
// ...
Here's the full file but I'm pretty sure I included all relevant parts in this whittled down version