URLSessionDelegate class deinit 未调用

URLSessionDelegate class deinit not called

对于客户端证书身份验证,我必须在自定义 class 中使用 URLSessionDelegate 来处理所有请求。问题是 class 在发出请求后未取消初始化。

代码:

class Request: NSObject, URLSessionDelegate, URLSessionTaskDelegate{
    
    
    func request(){
        
        let url:URL = URL(string: "https://whosebug.com")!
        
        let config = URLSessionConfiguration.default
        
        
        
        URLSession(configuration: config, delegate: self, delegateQueue: .main).dataTask(with: url) { (data, response, error) in
            
            print("Received")
            
        }.resume()
    }
    
    func request2(){
        
        let url:URL = URL(string: "https://whosebug.com")!
        
        let config = URLSessionConfiguration.default
        
        
        URLSession(configuration: config).dataTask(with: url) { (data, response, error) in
            
            print("Received")
            
        }.resume()
    }
    
    deinit {
        print("Class deinit...")
    }
}

调用 Request().request() 时不会调用 deinit。调用 Request().request2() 然后调用 deinit

我不确定如何解决这个问题。请帮我找出解决办法。谢谢...

request() 中,当将自己分配给委托时,您正在创建对 class 实例的强引用。这会导致保留周期并停止取消初始化实例。答案是每周抓委托:

URLSession(configuration: config, delegate: self, delegateQueue: .main).dataTask(with: url) { [weak self] (data, response, error) in
            
            print("Received")
            
        }.resume()

request2() 没有代表的情况下,这显然不会发生。

有很多关于此的博客和教程,所以我不会一一重复,我会让你 google 了解有关捕获列表和强引用和弱引用的详细信息:-)

URLSession 保留对其委托的强引用(self 在你的例子中)。检查 official documentation:

The session object keeps a strong reference to the delegate until your app exits or explicitly invalidates the session. If you don’t invalidate the session, your app leaks memory until the app terminates.

您可以使用其方法 finishTasksAndInvalidate()invalidateAndCancel() 使会话无效。之后 URLSession 将释放对其委托的强引用。

我猜你的代码示例只是为了演示行为,但无论如何我不得不提一下,为每个 URLRequest 创建一个新的 URLSession 不是一个好习惯。