我的代码有问题,我认为这可能与代码的调用顺序有关。
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。
我认为按时间顺序打印时task变量为空,以后再填充。
答案 0 :(得分:0)
当您尝试在willActivate()中打印任务数时,功能downloadJsonTask(url:String)尚未完成,因此您有空数组,因为尚未设置任务。
您应该像这样添加完成处理程序以下载JsonTask:
(不要忘记将完成作为函数的参数传递)
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)
}
因此,这意味着当您获取数据时,花括号中的代码将被执行。
答案 1 :(得分:0)
您正确的假设是,tasks
在首次打印时尚未分配值。
问题是网络请求是异步执行的。这意味着iOS不会等到downloadJsonTask(url:)
完成后才立即执行代码(即,它在网络请求启动之后立即调用print(tasks.count)
,而没有等待它执行产生任何结果。
URLSession.shared.dataTask(with:)
之后方括号内的代码段称为补全处理程序。一旦网络请求得到竞争,该代码即被执行(因此命名)。仅在请求完成时才为变量tasks
分配一个值。您可以通过在print(self.tasks.count)
之后添加self.tasks = downloadedTasks.tasks
来确保其有效:
self.tasks = downloadedTasks.tasks
print(self.tasks)
print(downloadedTasks.tasks.count)