您误解了异步代码的工作原理。
设置
NSSession数据任务时,在发出
task.resume()网络请求之前,将立即返回调用。
您应该将用于处理响应的代码放在完成处理程序中。即使您
The value here says 0在网络任务上调用恢复后发生打印语句,但尚未检索到数据。
想象一下,您正在做晚餐,然后您送孩子出去拿一袋面粉。你说:“孩子,给我拿点面粉。回来的时候,按下公寓门上的蜂鸣器,我会嗡嗡作响。”
然后,您又回到晚餐的其他部分做饭,但是您不希望告诉孩子去吃面粉的那一刻,您就会低头看着柜台,面粉就在那里了。您知道必须等到蜂鸣器发出嗡嗡声,然后您的孩子才能得到面粉。
提交网络任务就是这样。拨打电话
task.resume()类似于您对面粉的要求。您提交了请求,但是在请求完成处理之前继续进行 *** 作。在 完成处理程序
运行的是让你知道你的孩子又回来了面粉中的蜂鸣器。编辑:
我已经在Github上创建了一个项目,演示了如何在URLSession中使用完成处理程序。该项目称为
Async_demo
(链接)
关键部分是
downloadFileAtURL()DownloadManager.swift中的方法
注意函数如何将完成处理程序作为参数。该函数使用完成处理程序创建URLSession数据任务。在完成处理程序内部,对于
URLSession数据任务,该
downloadFileAtURL()函数调用传递给它的完成处理程序。它用于
DispatchQueue.main.async()在主线程上调用完成处理程序。
该演示项目使用
URLSession数据任务,并显式禁用数据缓存,以便每次单击下载按钮时都将重新加载映像。
这是
downloadFileAtURL()DownloadManager.swift中该函数的代码:
func downloadFileAtURL(_ url: URL, completion: @escaping DataClosure) { //We create a URLRequest that does not allow caching so you can see the download take place let request = URLRequest(url: url, cachePolicy: .reloadIgnoringLocalAndRemoteCacheData, timeoutInterval: 30.0) let dataTask = URLSession.shared.dataTask(with: request) { data, response, error in //Perform the completion handler on the main thread DispatchQueue.main.async { //Call the copmletion handler that was passed to us completion(data, error) } } dataTask.resume() //When we get here the data task will NOT have completed yet!}
视图控制器具有名为的IBAction函数
handledDownloadButton()。该功能:
- 禁用下载按钮并显示活动指示器视图。
- 调用下载管理器的downloadFileAtURL()以下载文件,并传入完成处理程序。完成处理程序会进行大量错误检查。如果一切顺利,它将把生成的数据转换为UIImage并将其安装在图像视图中,然后调用对图像进行一些动画处理的方法,然后丢弃该图像并重新启用下载按钮。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)