【问题标题】:URLSession.shared.dataTask vs dataTaskPublisher, when to use which?URLSession.shared.dataTask vs dataTaskPublisher,什么时候用哪个?
【发布时间】:2021-02-06 04:28:10
【问题描述】:

我最近遇到了两个数据获取(下载)API,它们对我来说似乎执行相同的操作。我不知道什么时候应该使用一个而不是另一个。

我可以使用URLSession.shared.dataTask

    var tasks: [URLSessionDataTask] = []

    func loadItems(tuple : (name : String, imageURL : URL)) {
        let task = URLSession.shared.dataTask(with: tuple.imageURL, completionHandler :
        { data, response, error in
            guard let data = data, error == nil else { return }
            DispatchQueue.main.async() { [weak self] in
                self?.displayFlag(data: data, title: tuple.name)
            }
        })
        tasks.append(task)
        task.resume()
    }

    deinit {
        tasks.forEach {
            $0.cancel()
        }
    }

或者我可以使用URLSession.shared.dataTaskPublisher

    var cancellables: [AnyCancellable] = []

    func loadItems(tuple : (name : String, imageURL : URL)) {
        URLSession.shared.dataTaskPublisher(for: tuple.imageURL)
            .sink(
                receiveCompletion: {
                    completion in
                    switch completion {
                    case .finished:
                        break
                    case .failure( _):
                        return
                    }},
                receiveValue: { data, _ in DispatchQueue.main.async { [weak self] in self?.displayFlag(data: data, title: tuple.name) } })
            .store(in: &cancellables)
    }

    deinit {
        cancellables.forEach {
            $0.cancel()
        }
    }

我看不出它们有明显的区别,因为两者都可以获取,并且都可以让我们轻松取消任务。有人可以阐明他们在何时使用 which 方面的差异吗?

【问题讨论】:

  • 第二个使用新的Combine框架
  • 他知道这一点。他在问为什么要使用组合模式。
  • 谢谢,@JoakimDanielson。我们什么时候应该使用原来的,什么时候应该使用Combine框架?使用 Combine 框架有什么好处?抱歉,我来自 Android Dev 背景,因此对 iOS 的了解有限。
  • 当克劳斯建议合并时,我认为他是在建议您不需要 deinit 清理。发布者发布后,请求应自动取消(这就是他在回答您的其他问题时推荐它的原因)。就我个人而言,如果它解决了其他问题(例如控制并发程度、链接其他发布者或组合操作符,已经将它用于项目中的其他事情),我会引入组合。我不确定我是否会在这里介绍它,只是为了不必手动取消请求,但这取决于你。这是一个见仁见智的问题。
  • 您需要阅读 Combine 并自行决定,但 Combine 是用于异步处理的新框架,因此可能值得考虑。

标签: ios swift urlsession


【解决方案1】:

第一个是经典。它已经存在了很长一段时间,而且大多数开发人员都熟悉它。

第二个是第一个的包装器,并允许将其与其他发布者组合(例如,仅在执行前两个请求时执行某些请求)。使用第一种方法组合数据任务要困难得多。

总而言之:将第一个用于一次性请求。当需要更多逻辑将结果与/传递给其他发布者(不仅来自 URLSession)时,请使用第二个。基本上,这就是 Combine 框架背后的理念——您可以组合不同方式的异步机制(利用回调的数据任务就是其中之一)。

更多信息可以在去年的 WWDC 视频中找到,介绍 combine。

【讨论】:

  • 谢谢@Eimantas。我会进一步检查heckj.github.io/swiftui-notes。对于上面的代码,我还应该为deinit中的cancelablecancel吗?这是多余的吗?
  • 我对cancellables的行为不是很熟悉。你可以在receiveValue块中打印一些东西,看看它是否在你释放实例hding cancellables后打印任何东西。
  • 我在这里检查它声明它应该可以自行取消。 stackoverflow.com/a/59023309/3286489
猜你喜欢
  • 2019-02-15
  • 2013-02-20
  • 1970-01-01
  • 2015-10-27
  • 1970-01-01
  • 1970-01-01
  • 2015-11-30
  • 2022-06-18
  • 2016-09-09
相关资源
最近更新 更多