从完成处理程序中获取一个 value/object 到它之外的数组中
Get a value/object from a completion handler into an array that is outside of it
我有从服务器获取的数据并使用 JSON 解析该数据。所以我有一个 URL 会话。这个数据被正确解析了,因为我为它使用了一个与接收到的字典中的键相同的结构,但问题是当我 'convert' 这个数据到这个对象时,我无法存储这个对象在完成处理程序范围之外的数组中。
使用的函数:
fileprivate func loadColor(_ urlString: URL?, completionHandler: @escaping (Color) -> Void) {
if let url = urlString {
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
if error != nil {
print(error)
} else {
do {
if let data = data,
let color = try JSONSerialization.jsonObject(with: data) as? [String: Any] {
guard let color2 = Color(json: color) else
{
fatalError("something didn't go as planned")
}
completionHandler(color2)
}
} catch {
print("Error deserializing JSON: \(error)")
}
}
}
task.resume()
}
}
我在 viewDidLoad() 中调用了这个方法并尝试将其放入这样的数组中:
var colors : [Color] = []
override func viewDidLoad() {
super.viewDidLoad()
loadColor(URL(string: "API command here"), completionHandler: { color in
self.colors.append(color)
print("\(self.colors.count)")
})
print("\(self.colors.count)")
}
当我在颜色数组上执行追加时,它确实将它添加到数组中,因为在打印计数时它从 0 变为 1,但是当我超出此完成处理程序的范围时,数组再次为空。
我错过了什么?
您的代码看起来完全没问题 - 您的网络调用之外的 print
语句打印 0 值的原因是 API 调用是异步的,因此它将在该打印语句之后完成执行。如果您的数组确实被设置回空数组,那么它一定发生在其他地方。
您可以为调试做的一件事可能是观察该变量,看看它何时像这样设置:
var colors: [Color] = [] {
didSet {
//This will be called every time this array is set/changed
print(colors.count)
}
}
您甚至可以在 didSet
内的 print 语句上放置一个断点,这样您就可以看到重置数组的痕迹。
不过,我再次怀疑您的代码没有问题,您只是对异步完成时间感到困惑。
我有从服务器获取的数据并使用 JSON 解析该数据。所以我有一个 URL 会话。这个数据被正确解析了,因为我为它使用了一个与接收到的字典中的键相同的结构,但问题是当我 'convert' 这个数据到这个对象时,我无法存储这个对象在完成处理程序范围之外的数组中。
使用的函数:
fileprivate func loadColor(_ urlString: URL?, completionHandler: @escaping (Color) -> Void) {
if let url = urlString {
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
if error != nil {
print(error)
} else {
do {
if let data = data,
let color = try JSONSerialization.jsonObject(with: data) as? [String: Any] {
guard let color2 = Color(json: color) else
{
fatalError("something didn't go as planned")
}
completionHandler(color2)
}
} catch {
print("Error deserializing JSON: \(error)")
}
}
}
task.resume()
}
}
我在 viewDidLoad() 中调用了这个方法并尝试将其放入这样的数组中:
var colors : [Color] = []
override func viewDidLoad() {
super.viewDidLoad()
loadColor(URL(string: "API command here"), completionHandler: { color in
self.colors.append(color)
print("\(self.colors.count)")
})
print("\(self.colors.count)")
}
当我在颜色数组上执行追加时,它确实将它添加到数组中,因为在打印计数时它从 0 变为 1,但是当我超出此完成处理程序的范围时,数组再次为空。 我错过了什么?
您的代码看起来完全没问题 - 您的网络调用之外的 print
语句打印 0 值的原因是 API 调用是异步的,因此它将在该打印语句之后完成执行。如果您的数组确实被设置回空数组,那么它一定发生在其他地方。
您可以为调试做的一件事可能是观察该变量,看看它何时像这样设置:
var colors: [Color] = [] {
didSet {
//This will be called every time this array is set/changed
print(colors.count)
}
}
您甚至可以在 didSet
内的 print 语句上放置一个断点,这样您就可以看到重置数组的痕迹。
不过,我再次怀疑您的代码没有问题,您只是对异步完成时间感到困惑。