函数的顺序-哪些代码在什么时候运行



我的代码有问题,我认为这可能与调用代码的顺序有关。

import WatchKit
import Foundation

class InterfaceController: WKInterfaceController {
private var tasks = [Task]()
override func willActivate() {
let taskUrl = "http://myjsonurl.com"
downloadJsonTask(url: taskUrl)
print(tasks.count) // EMPTY
super.willActivate()
}
func downloadJsonTask(url: String) {
var request = URLRequest(url: URL(string: url)!)
request.cachePolicy = URLRequest.CachePolicy.reloadIgnoringLocalCacheData
URLSession.shared.dataTask(with: request) { data, urlResponse, error in
guard let data = data, error == nil, urlResponse != nil else {
print("something is wrong")
return
}
do
{
let decoder = JSONDecoder()
let downloadedTasks = try decoder.decode(Tasks.self, from: data)
self.tasks = downloadedTasks.tasks
print(downloadedTasks.tasks.count) //4
} catch {
print("somehting went wrong after downloading")
}
}.resume()
}
}

我定义了private var tasks,并用downloadJsonTask函数填充它,但在函数运行后,print(tasks.count)给出0。当我调用print(downloadedTasks.tasks.count)时,它给出4。

我认为按时间顺序,当我打印任务变量时,它是空的,稍后会被填充

当您试图在willActivate((中打印任务数时,函数downloadJsonTask(url:String(尚未完成,因此您有空数组,因为任务尚未设置。

您应该向downloadJsonTask添加完成处理程序,如下所示:

(不要忘记将完成作为函数的参数(

func downloadJsonTask(url: String, completion: @escaping () -> Void) {
var request = URLRequest(url: URL(string: url)!)
request.cachePolicy = URLRequest.CachePolicy.reloadIgnoringLocalCacheData
URLSession.shared.dataTask(with: request) { data, urlResponse, error in
guard let data = data, error == nil, urlResponse != nil else {
print("something is wrong")
completion()
return
}
do {
let decoder = JSONDecoder()
let downloadedTasks = try decoder.decode(Tasks.self, from: data)
self.tasks = downloadedTasks.tasks
print(downloadedTasks.tasks.count) //4
} catch {
print("something went wrong after downloading")
}
completion() // This is moment when code which you write inside closure get executed
}.resume()
}

在你的willActivate((中使用这样的函数:

downloadJsonTask(url: taskUrl) { 
print(tasks.count)
}

因此,这意味着当您获得数据时,大括号内的代码将被执行。

您的假设是正确的,即tasks在首次打印时尚未分配值。

问题是网络请求是异步执行的。这意味着iOS不会等到downloadJsonTask(url:)完成,而是立即继续执行代码(即在网络请求启动后立即调用print(tasks.count),而不等待它产生任何结果(。

URLSession.shared.dataTask(with:)后面括号内的代码称为完成处理程序。一旦网络请求被竞争,就会执行此代码(因此得名(。只有当请求完成时,才会为tasks变量分配一个值。您可以通过在self.tasks = downloadedTasks.tasks:之后添加print(self.tasks.count)来确保其工作

self.tasks = downloadedTasks.tasks
print(self.tasks)
print(downloadedTasks.tasks.count)

相关内容

  • 没有找到相关文章

最新更新