从图像url下载图像方面,URLSession vs DispatchQueue.global().async + Data(contentsOf: )
有何区别?
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
提供了更大的配置控制,故障诊断,取消,后台 session ,直接下载到永久性存储以最大程度减少峰值内存使用量的能力等。URLSession
和Data(contentsOf:)
在功能集上是无法比拟的。
同步Data(contentsOf:)
不必要地阻塞了GCD工作线程,也容易被滥用。这也是非常有限的,将来您会很后悔自己的决定(例如,稍后添加一些身份验证过程;您想要自定义缓存行为,想要解析并根据响应中的状态代码采取操作,需要取消操作)功能,因为您正在检索图像以进行集合视图或表格视图等)。
使用init
的URL方法查看Data
之一的the documentation很有启发性,它在其中警告我们:
重要
不要使用此同步初始化程序来请求基于网络的URL。对于基于网络的URL,此方法可能会在慢速网络上将当前线程阻塞数十秒钟,从而导致较差的用户体验,并且在iOS中,可能会导致您的应用终止。
相反,对于非文件URL,请考虑使用 dataTask(with:completionHandler:)
类的 URLSession
方法。有关示例,请参见Fetching Website Data into Memory。
是的,将其分配给后台线程可以解决上述许多问题,但Apple并不仅建议“仅将其分配给某些后台队列”,而是明确建议改用URLSession
。尽管您使用GCD全局队列可以避免Apple在上面警告我们的一些问题,但它也施加了许多不必要的限制。如果您使用Data(contentsOf:)
,那么这个决定将来可能会令您后悔/重构。您最好现在使用URLSession
。
关于使用Data(contentsOf:)
,.userInitiated
或.default
方法时URLSession
明显更快,通常网络延迟和传输时间使所有与队列优先级相关的因素相形见,,因此我很难相信这一说法。实际上,我刚刚通过GCD测试了50张图片的下载(同时使用.default
和.userInitiated
),并且速度与URLSession
方法没有明显的不同。
关于ios - 从图片url下载图片方面,URLSession与GCD有何区别?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55332857/