gpt4 book ai didi

Swift Combine - CFString(存储)内存泄漏

转载 作者:行者123 更新时间:2023-12-03 17:10:19 24 4
gpt4 key购买 nike

在 xcode 中使用内存图调试器时,我看到了一些内存泄漏。 Backtrace 没有直接链接到我的任何代码,而是通过跟踪猜测它的保存以假设它与组合和一些 DataTaskPublisher 相关。
enter image description here
接下来我检查了 Instruments 内部,在那里我也看到了一些内存泄漏。所有泄漏都在堆栈跟踪中提到“专门的静态 UIApplicationDelegate.main()”,但它并没有真正链接到可能导致内存泄漏的东西。
enter image description here
删除负责从 API 加载数据的 ViewModel 可以消除泄漏。内存图调试器显示了一个 dataTaskPublisher,所以这有点道理。

import Foundation
import Combine

enum API {
static func games() -> AnyPublisher<[GameResult], Error> {
let requestHeaderGames = gamesRequest()

return URLSession.shared.dataTaskPublisher(for: requestHeaderGames)
.map(\.data)
.decode(type: [GameResult].self, decoder: JSONDecoder())
.receive(on: DispatchQueue.main)
.eraseToAnyPublisher()
}

private static func gamesRequest() -> URLRequest {
let url = URL(string: "http://localhost:8080/api/games")!
var requestHeader = URLRequest.init(url: url)
requestHeader.httpBody =
"filter ..."
.data(using: .utf8, allowLossyConversion: false)

requestHeader.httpMethod = "POST"
requestHeader.setValue("application/json", forHTTPHeaderField: "Accept")

return requestHeader
}
}

struct GameResult: Decodable, Identifiable, Equatable, Hashable {
let id: Int
// ...
}

final class ViewModel: ObservableObject {
@Published private(set) var games: [GameResult] = []

private var subscriptions = Set<AnyCancellable>()

public func unsubscribe() -> Void {
subscriptions.forEach {
$0.cancel()
}
subscriptions.removeAll()
}

func load() -> Void {
API.games()
.sink(receiveCompletion: { _ in }, receiveValue: { [weak self] results in
self?.games = results
})
.store(in: &subscriptions)
}
}
我已经花了很多时间来弄清楚是什么导致了这个泄漏,但我比其他任何事情都更困惑。 CFString 不是我使用的任何东西。我也无法找出为什么我的代码似乎导致了这种泄漏。
有什么我只是缺少的东西,或者有人可以通过给我一些建议来帮助我解决这个问题吗?

最佳答案

您发布的第一张图片似乎表明这是解码器发布商的问题。我会尝试几个不同的场景,看看我们是否可以通过解码来隔离问题:

enum API {

static var fakeGameData: Data {
let encoder = JSONEncoder()
return try! encoder.encode(fakeGames)
}

static var fakeGames: [GameResult] {
return [GameResult(id: 0), GameResult(id: 2), GameResult(id: 3)]
}

static func gamesFromData() -> AnyPublisher<[GameResult], Error> {
return Just(fakeGameData)
.decode(type: [GameResult].self, decoder: JSONDecoder())
.mapError({ $0 as Error })
.eraseToAnyPublisher()
}

static func gamesFromArray() -> AnyPublisher<[GameResult], Error> {
return Just(fakeGames)
.mapError({ $0 as Error })
.eraseToAnyPublisher()
}
}
看看如果您订阅 API.gamesFromData() 会发生什么。如果您仍然看到泄漏,则可能是解码器的问题。如果没有,那么您很有可能在 dataTaskPublisher 上遇到问题。
然后,看看如果您订阅 API.gamesFromArray() 会发生什么。如果您仍然看到泄漏,那么您就知道问题不在于解码器发布者。

关于Swift Combine - CFString(存储)内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64617423/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com