swift - 函数顺序 - 哪个代码在什么时候运行?
swift - order of functions - which code runs when?
我的代码有问题,我认为这可能与调用代码的顺序有关。
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)
}
这意味着当您获取数据时,curly 大括号内的代码将被执行。
您的假设是正确的,即 tasks
在首次打印时尚未被赋值。
问题是网络请求是异步执行的。这意味着 iOS 不会等到 downloadJsonTask(url:)
完成,而是立即继续执行代码(即它在网络请求 started[=26= 后立即调用 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)
我的代码有问题,我认为这可能与调用代码的顺序有关。
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)
}
这意味着当您获取数据时,curly 大括号内的代码将被执行。
您的假设是正确的,即 tasks
在首次打印时尚未被赋值。
问题是网络请求是异步执行的。这意味着 iOS 不会等到 downloadJsonTask(url:)
完成,而是立即继续执行代码(即它在网络请求 started[=26= 后立即调用 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)