gpt4 book ai didi

swift - 有或没有[弱 self ]

转载 作者:行者123 更新时间:2023-12-02 02:23:42 30 4
gpt4 key购买 nike

我有一个非常奇怪的情况。我的服务器当前已关闭并收到 503 http 状态代码。基于如下给定的代码,代码进入 if 条件,但是当我将调试点置于 let error = self?.decodeErrorMessage(data: data, statusCode: response.statusCode) 时。然后它从 if 条件跳转并执行 else if 条件。

ClientViewModel.swift

let networkRequest = CustomNetworkRequest(headers: headers, httpMethod: .get, httpBody: nil, parameters: nil, url: url)

let customNetworker = CustomNetworker(urlSession: URLSession(configuration: config))
customNetworker.dataRequest(networkRequest, successHandler: {[weak self] data in
self?.parseData(data)
completion(nil)
}, failureHandler: { [weak self] error in
completion(error)
})

CustomNetworker.swift

final class CustomNetworker {
private let urlSession: URLSession

public init(urlSession: URLSession) {
self.urlSession = urlSession
}
func dataRequest(input parameters here) {
let task = urlSession.dataTask(with: urlRequest) {[weak self] data, response, error in
if let response = response as? HTTPURLResponse , 300...599 ~= response.statusCode,
let data = data,
let error = self?.decodeErrorMessage(data: data, statusCode: response.statusCode) {
failureHandler(error)
} else if let error = error {
failureHandler(error)
} else if let data = data {
successHandler(data)
} else {
failureHandler(error)
}
}
task.resume()
}
}

但是,如果我删除 [weak self] 那么它会按预期工作,它会调用该方法。如何正确解决问题?

let task = urlSession.dataTask(with: urlRequest) {data, response, error in
if let response = response as? HTTPURLResponse , 300...599 ~= response.statusCode,
let data = data,
let error = self.decodeErrorMessage(data: data, statusCode: response.statusCode) {
failureHandler(error)
}
else if let error = error {
failureHandler(error)
} else if let data = data {
successHandler(data)
} else {
failureHandler(error)
)
}
}
task.resume()

decodeErrorMessage 方法

private func decodeErrorMessage(data: Data, statusCode: Int) -> CustomError?  {
// not coming into this method
if let errorData = try? JSONDecoder.convertFromSnakeCaseDecoder.decode(CustomServiceError.self, from: data) as CustomServiceError? {
if let errorData = errorData {
return formCustomError(something here)
}
return CustomError.genericError(debugMessage: debugMessage, sourceError: nil)
} else if let errorMessage = StatusCode(rawValue: statusCode) {
let debugMessage = String(data:data, encoding: .utf8)
return formCustomError(something here)
} else {
let debugMessage = String(data:data, encoding: .utf8)
return formCustomError(something here)
}
}

最佳答案

问题是您已将 customNetworker(CustomNetworker)设为局部变量,并且一旦该局部变量脱离范围。当 dataRequest(input:) 方法使用 [weak self] 引用时,它表示您不需要 dataRequest(input:)保持对此 CustomNetworker 实例的强引用。因此,如果没有强引用,CustomNetworker 将被释放。

你有几个选择:

  1. 如果您在 dataRequest(input:) 内的闭包中删除了 [weak self] 引用,那么它将保留 CustomNetworker 直到闭包运行。只要您不将此 failureHandler(和其他闭包)保存为存储属性,就应该没问题。但是不要只是扔进一个[weak self]因为你在某处读到你应该总是使用弱引用。在需要避免强引用循环的地方使用弱引用,这里似乎不是这种情况。

  2. 另一种方法是重构此代码,将此网络请求例程 dataRequest(input:) 移动到某个生命周期更长的对象。

    例如,我们通常有一个长期存在的网络管理器对象,它维护 URLSession 并具有所有这些与网络相关的方法。然后,假设您在其他地方保持对该网络管理器实例的强引用,则无需担心该对象在超出范围时被释放。这也使您不必为每个请求传入 URLSession 对象。无论如何,调用者不应处理这些 URLSession 实例。

    例如,我经常使用单例网络层(类似于 URLSession.shared 模式):

    final class NetworkManager {
    static let shared = NetworkManager()

    private var session: URLSession = .shared // or create and configure this session as you need; but one session object is all you need

    private init() { }

    @discardableResult
    func performRequest(...) -> URLSessionTask {
    ...
    let task = session.dataTask(...) { [weak self] data, response, error in
    ...
    }
    task.resume()
    return task
    }
    }

    然后你可以这样做:

    NetworkManager.shared.performRequest(...) { [weak self] ... in
    ...
    }
  3. 另一种选择是只保留对此 customNetworker 变量的强引用(例如,将其设为属性而不是局部变量)。这将防止 CustomNetworker 对象超出范围并变为 nil,因为没有更多对它的强引用。


有点不相关,但当您实例化您的 CustomNetworker 对象时,您似乎正在创建一个 URLSession 对象,并且随后永远不会使其无效。这会泄漏。您应该创建一个 URLSession 对象并将其用于所有后续网络请求。

如果您确实创建了多个 URLSession 对象,则必须在使用完后使每个对象失效(例如 finishTasksAndInvalidate ),否则就会泄漏。但是,如果您只有一个 session 可以为所有 future 的网络请求保持事件状态(这是首选),那么就没有必要了。

关于swift - 有或没有[弱 self ],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66051875/

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