从图像 url 下载图像方面,URLSession 与 GCD 有啥区别?
Posted
技术标签:
【中文标题】从图像 url 下载图像方面,URLSession 与 GCD 有啥区别?【英文标题】:What is difference between URLSession vs GCD in terms of download image from image url?从图像 url 下载图像方面,URLSession 与 GCD 有什么区别? 【发布时间】:2019-03-25 07:17:54 【问题描述】:URLSession vs DispatchQueue.global().async + Data(contentsOf: )
从图片 url 下载图片有什么区别?
func loadImageWithUrlSession()
guard let url = URL(string: IMAGE_URL) else return
URLSession.shared.dataTask(with: url) (data, response, error) in
if let error = error
print(error.localizedDescription)
return
guard let data = data else return
let image = UIImage(data: data)
DispatchQueue.main.async [weak self] in
guard let self = self else return
self.urlSessionImageView.image = image
.resume()
func loadImageWithGCD()
DispatchQueue.global(qos: .background).async
guard
let url = URL(string: self.IMAGE_URL),
let data = try? Data(contentsOf: url) else
return
let image = UIImage(data: data)
DispatchQueue.main.async [weak self] in
guard let self = self else return
self.gcdImageView.image = image
我知道URLSession
可以取消或暂停任务。
但是如果我改用 Rx,我也可以做和上面一样的事情。
我做了一个实验,这取决于我使用的 QoS。 顺便说一句,.userInitiated QoS 比 URLSession 快得多。 你们将哪一个用于诸如通过后台线程下载任务之类的事情,为什么?
有没有哪位好心的老师可以具体帮帮我?
【问题讨论】:
使用 UrlSession 代替 Data(contentsOf: url)。第一个是异步的,第二个是同步的。不要使用此同步初始化程序来请求基于网络的 URL。对于基于网络的 URL,这种方法会在慢速网络上阻塞当前线程数十秒,导致用户体验不佳,并且在 ios 中可能会导致您的应用被终止。相反,对于非文件 URL,请考虑使用 URLSession 类的 dataTask(with:completionHandler:) 方法。 还可以查看以下链接:developer.apple.com/documentation/foundation/nsdata/… 【参考方案1】:URLSession
提供了更强大的配置控制、故障诊断、取消、后台会话、直接下载到持久存储以最小化峰值内存使用的能力等。URLSession
和 Data(contentsOf:)
在功能集上没有可比性.
同步的Data(contentsOf:)
会不必要地阻塞 GCD 工作线程并且也容易被误用。这也是相当有限的,你很容易发现自己在将来后悔这个决定(例如,你稍后添加一些身份验证过程;你想自定义缓存行为,你想解析响应中的状态码并采取行动,你需要取消功能,因为您正在检索图像以用于集合或表格视图等)。
使用Data
的 URL 方法查看 the documentation 中的一个 init
是很有启发性的,它会警告我们:
重要
不要使用此同步初始化程序来请求基于网络的 URL。对于基于网络的 URL,此方法会在慢速网络上阻塞当前线程数十秒,导致用户体验不佳,并且在 iOS 中可能会导致您的应用被终止。
对于非文件 URL,请考虑使用
URLSession
类的dataTask(with:completionHandler:)
方法。示例见Fetching Website Data into Memory。
是的,将其分派到后台线程解决了上述许多问题,但 Apple 不仅建议“将其分派到某个后台队列”,而是明确建议改用 URLSession
。虽然您使用 GCD 全局队列避免了 Apple 在上面警告我们的一些问题,但它也施加了许多不必要的限制。如果您使用Data(contentsOf:)
,这是您将来可能会后悔/重构的决定。您不妨现在使用URLSession
。
关于Data(contentsOf:)
在使用.userInitiated
时明显更快,与.default
或URLSession
方法相比,通常网络延迟和传输时间使任何与队列优先级相关的因素相形见绌,所以我觉得这种说法很难相信。事实上,我刚刚测试了通过 GCD 下载 50 张图片(同时使用 .default
和 .userInitiated
),速度与 URLSession
方法没有明显不同。
【讨论】:
以上是关于从图像 url 下载图像方面,URLSession 与 GCD 有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章