如果我使用单例网络服务发出网络请求,是不是需要使用 [weak self]?

Posted

技术标签:

【中文标题】如果我使用单例网络服务发出网络请求,是不是需要使用 [weak self]?【英文标题】:Do I need to use [weak self] if I'm making a network request using a singleton networking service?如果我使用单例网络服务发出网络请求,是否需要使用 [weak self]? 【发布时间】:2018-07-01 09:28:47 【问题描述】:

假设我有一个使用 Alamofire 的 SessionManager 的网络单例,例如:

导入 Alamofire

class Network 
    static let shared = Network()
    private init() 

    private var sessionManager: SessionManager = 
        let configuration = URLSessionConfiguration.default
            configuration.httpAdditionalHeaders = SessionManager.defaultHTTPHeaders

                return SessionManager(configuration: configuration)
    

    func postRequest(params: [String: Any]? = nil, completion: (() -> ())? = nil) 
        sessionManager.request(url, method: .post, parameters: params).validate().responseData 
            // do something with response
            completion()
        
      

然后我在服务类中使用它:

class SomeService 
    static let shared = SomeService()
    private init() 

    func doSomePostRequest(params: [String: Any]? = nil, completion: (() -> ())? = nil) 
        Network.shared.postRequest(params: params, completion: completion)
    

然后我提出一个请求并使用这个服务类重新加载一个表格视图:

class MyViewController: UITableViewController 
    @IBAction func fetchData(_: Any)  
        SomeService.shared.doSomePostRequest 
            // do i need to use [weak self] here?
            self.tableView.reloadData()
        
    

我还需要使用 [weak self] 来避免崩溃和强引用循环吗?在任何时候,用户都可以通过按 Back 来关闭 MyViewController。

我是否正确假设我不需要它,因为服务类是单例的?如果我在 MyViewController 中将其作为一个实例,我就必须使用 [weak self]?

【问题讨论】:

【参考方案1】:

您使用对对象的弱引用来确保它们在应该被释放的时候被释放。

单例永远不会被释放。因此,您是否有一个强、弱或不安全的指针并不重要。无需使参考变弱。

【讨论】:

你应该看看他发布的代码。弱引用是 MyViewController,不是单例。 我现在明白了。当闭包在单例中解析时,MyViewController 被释放,因为它没有将单例引用为实例属性。【参考方案2】:

我不具体了解 Alamofire 的 SessionManager,但总的来说,是的,即使您使用的是单例,您也需要防止额外的保留。事实上,您必须防范它们尤其是,因为它们是单身人士。

查看您的代码,您担心的self 是MyViewController。如果您在单例 SomeService 中创建对 MyViewController 的强引用,则 MyViewController 将永远被释放,因为您的单例在应用程序的整个生命周期中都存在。这并不是一个真正的循环保留(它不是循环的),但效果是一样的——MyViewController 和它保留的所有对象永远不会被释放。

【讨论】:

以上是关于如果我使用单例网络服务发出网络请求,是不是需要使用 [weak self]?的主要内容,如果未能解决你的问题,请参考以下文章

是否可以从另一个网络向服务器发出请求

为啥没有网络连接时 Alamofire 需要这么长时间才能超时?

发出许多网络请求的 iOS 应用程序的最佳架构?

Flutter中的单例以及网络请求库的封装

弹性 IP 是不是会更改传出请求的网络路由?

javascript不会发出网络请求