首页 > 解决方案 > URLSessionTask 实例变量与局部变量 - 谁拥有引用?

问题描述

请参考下面的代码片段(与问题无关的部分省略)

在 WebService1 中,dataTask 是实例变量/属性,而在 WebService2 中,dataTask 是函数 callWebService 内的局部变量。

final class WebService1 {
    let urlSession = URLSession(configuration: .default)

    // 1. data task is a private property of PNWebService here

    private var dataTask: URLSessionDataTask?
    func callWebService(completion: () -> ()) {
        var urlRequest = URLRequest(url: url)
        dataTask = urlSession.dataTask(with: urlRequest) { 
           // task complete
           completion()
        }
        dataTask?.resume()
    }
}


final class WebService2 {
    let urlSession = URLSession(configuration: .default)

    func callWebService(completion: () -> ()) {
        var urlRequest = URLRequest(url: url)

        // 2. data task is a local variable here
        var dataTask = urlSession.dataTask(with: url) { 
            // task complete
            completion()
        }
        dataTask.resume()
    }
}

客户以通常的方式调用这两个服务:

let ws1 = WebService1()
ws1.callWebService() {
    print("1. complete")
}

let ws2 = WebService2()
ws2.callWebService() {
    print("2. complete")
}

Q1) 谁拥有对 WebService2 中 dataTask 的强引用,以便在调用完成处理程序之前不会释放它?

Q2) 从客户端的角度来看,WebService1 和 WebService2 在运行时有什么区别?

标签: iosswiftautomatic-ref-countingurlsession

解决方案


你问哪种模式是正确的?两者都不。URLSession 拥有数据任务并在您第一次使用它时立即管理其内存resume,因此您无需保留对它的任何引用,除非您打算对该引用执行其他操作,例如进一步配置任务或稍后取消操作。一般来说,这样说就足够了,而且很平常

urlSession.dataTask(with:url) { data, resp, err in
    // whatever
}.resume()

推荐阅读