避免Swift同时调用viewDidLoad中的方法得到"Index out of range"
Avoid Swift Calling methods in viewDidLoad at the same time and getting "Index out of range"
你能帮我一下吗?我想知道如何在另一个函数结束后调用 swift 函数,我认为它是同时调用两个函数。这是我的 viewDidLoad:
override func viewDidLoad() {
super.viewDidLoad()
downloadJsonEscuelas(id_responsable: "5")
downloadJsonAnuncios(id_escuela:("\arrayEscuelas[0].id_escuela!)"))
}
第一个函数"downloadJsonEscuelas"用数据填充数组"arrayEscuelas",第二个函数接收数据作为参数:
下载JsonEscuelas:
func downloadJsonEscuelas(id_responsable: String) {
guard let downloadURL = URL(string: Constantes.URLbase+"json/getescuelas.php?id="+id_responsable) else { return }
URLSession.shared.dataTask(with: downloadURL) { data, urlResponse,
error in
guard let data = data, error == nil, urlResponse != nil else {
print("Something went wrong")
return
}
print("Escuelas downloaded")
do
{
let downloadedEscuelas = try JSONDecoder().decode([Escuelas].self, from: data)
self.arrayEscuelas = downloadedEscuelas
DispatchQueue.main.async {
print("id escuela actual:"+self.idEscuelaActual!+":)")
self.escuelaTextBox.text = self.arrayEscuelas[0].escuela!
self.idEscuelaActual = "\(self.arrayEscuelas[0].id_escuela!)" as String
}
} catch let jsonErr {
print("Error: ", jsonErr)
}
}.resume()
}
下载JsonAnuncios:
func downloadJsonAnuncios(id_escuela: String) {
guard let downloadURL = URL(string: Constantes.URLbase+"json/getanuncios.php?id="+id_escuela) else { return }
URLSession.shared.dataTask(with: downloadURL) { data, urlResponse,
error in
guard let data = data, error == nil, urlResponse != nil else {
print("Something went wrong")
return
}
print("downloaded")
do
{
let downloadedAnuncios = try JSONDecoder().decode([Anuncios].self, from: data)
self.arrayAnuncios = downloadedAnuncios
print(self.arrayAnuncios[0].titulo!)
DispatchQueue.main.async {
self.tableView.reloadData()
}
} catch let jsonErr {
print("Error: ", jsonErr)
}
}.resume()
}
我认为它同时调用了两个函数,所以它没有在第一个函数中填充数组。当我将参数作为普通数字传递时,一切顺利,例如:
downloadJsonAnuncios(id_escuela: "2")
希望你能帮到我,非常感谢。
在第一个调用 (downloadJsonEscuelas(id_responsable: "5")
) 的完成中插入第二个调用 (this downloadJsonAnuncios(id_escuela:("\arrayEscuelas[0].id_escuela!)"))
)
func downloadJsonEscuelas(id_responsable: String) {
guard let downloadURL = URL(string: Constantes.URLbase+"json/getescuelas.php?id="+id_responsable) else { return }
URLSession.shared.dataTask(with: downloadURL) { data, urlResponse,
error in
guard let data = data, error == nil, urlResponse != nil else {
print("Something went wrong")
return
}
print("Escuelas downloaded")
do
{
let downloadedEscuelas = try JSONDecoder().decode([Escuelas].self, from: data)
self.arrayEscuelas = downloadedEscuelas
DispatchQueue.main.async {
print("id escuela actual:"+self.idEscuelaActual!+":)")
self.escuelaTextBox.text = self.arrayEscuelas[0].escuela!
self.idEscuelaActual = "\(self.arrayEscuelas[0].id_escuela!)" as String
}
// here
downloadJsonAnuncios(id_escuela:("\arrayEscuelas[0].id_escuela!)"))
} catch let jsonErr {
print("Error: ", jsonErr)
}
}.resume()
}
为什么不在第一个的闭包中调用第二个
do {
let downloadedEscuelas = try JSONDecoder().decode([Escuelas].self, from: data)
self.arrayEscuelas = downloadedEscuelas
DispatchQueue.main.async {
print("id escuela actual:"+self.idEscuelaActual!+":)")
self.escuelaTextBox.text = self.arrayEscuelas[0].escuela!
self.idEscuelaActual = "\(self.arrayEscuelas[0].id_escuela!)" as String
}
downloadJsonAnuncios(id_escuela:("\arrayEscuelas[0].id_escuela!)"))
} catch let jsonErr {
print("Error: ", jsonErr)
}
}.resume()
默认情况下,viewDidLoad 中的代码在 UIThread 上同步运行。
您的 API 调用在单独的线程上 运行 并且允许您的其他方法在完成之前执行。
您可能应该在您的方法中使用完成处理程序,这样您的第二个方法只会在您的 api 调用完成后被调用。
查看此答案以实施 CompletionHandler
你能帮我一下吗?我想知道如何在另一个函数结束后调用 swift 函数,我认为它是同时调用两个函数。这是我的 viewDidLoad:
override func viewDidLoad() {
super.viewDidLoad()
downloadJsonEscuelas(id_responsable: "5")
downloadJsonAnuncios(id_escuela:("\arrayEscuelas[0].id_escuela!)"))
}
第一个函数"downloadJsonEscuelas"用数据填充数组"arrayEscuelas",第二个函数接收数据作为参数:
下载JsonEscuelas:
func downloadJsonEscuelas(id_responsable: String) {
guard let downloadURL = URL(string: Constantes.URLbase+"json/getescuelas.php?id="+id_responsable) else { return }
URLSession.shared.dataTask(with: downloadURL) { data, urlResponse,
error in
guard let data = data, error == nil, urlResponse != nil else {
print("Something went wrong")
return
}
print("Escuelas downloaded")
do
{
let downloadedEscuelas = try JSONDecoder().decode([Escuelas].self, from: data)
self.arrayEscuelas = downloadedEscuelas
DispatchQueue.main.async {
print("id escuela actual:"+self.idEscuelaActual!+":)")
self.escuelaTextBox.text = self.arrayEscuelas[0].escuela!
self.idEscuelaActual = "\(self.arrayEscuelas[0].id_escuela!)" as String
}
} catch let jsonErr {
print("Error: ", jsonErr)
}
}.resume()
}
下载JsonAnuncios:
func downloadJsonAnuncios(id_escuela: String) {
guard let downloadURL = URL(string: Constantes.URLbase+"json/getanuncios.php?id="+id_escuela) else { return }
URLSession.shared.dataTask(with: downloadURL) { data, urlResponse,
error in
guard let data = data, error == nil, urlResponse != nil else {
print("Something went wrong")
return
}
print("downloaded")
do
{
let downloadedAnuncios = try JSONDecoder().decode([Anuncios].self, from: data)
self.arrayAnuncios = downloadedAnuncios
print(self.arrayAnuncios[0].titulo!)
DispatchQueue.main.async {
self.tableView.reloadData()
}
} catch let jsonErr {
print("Error: ", jsonErr)
}
}.resume()
}
我认为它同时调用了两个函数,所以它没有在第一个函数中填充数组。当我将参数作为普通数字传递时,一切顺利,例如:
downloadJsonAnuncios(id_escuela: "2")
希望你能帮到我,非常感谢。
在第一个调用 (downloadJsonEscuelas(id_responsable: "5")
) 的完成中插入第二个调用 (this downloadJsonAnuncios(id_escuela:("\arrayEscuelas[0].id_escuela!)"))
)
func downloadJsonEscuelas(id_responsable: String) {
guard let downloadURL = URL(string: Constantes.URLbase+"json/getescuelas.php?id="+id_responsable) else { return }
URLSession.shared.dataTask(with: downloadURL) { data, urlResponse,
error in
guard let data = data, error == nil, urlResponse != nil else {
print("Something went wrong")
return
}
print("Escuelas downloaded")
do
{
let downloadedEscuelas = try JSONDecoder().decode([Escuelas].self, from: data)
self.arrayEscuelas = downloadedEscuelas
DispatchQueue.main.async {
print("id escuela actual:"+self.idEscuelaActual!+":)")
self.escuelaTextBox.text = self.arrayEscuelas[0].escuela!
self.idEscuelaActual = "\(self.arrayEscuelas[0].id_escuela!)" as String
}
// here
downloadJsonAnuncios(id_escuela:("\arrayEscuelas[0].id_escuela!)"))
} catch let jsonErr {
print("Error: ", jsonErr)
}
}.resume()
}
为什么不在第一个的闭包中调用第二个
do {
let downloadedEscuelas = try JSONDecoder().decode([Escuelas].self, from: data)
self.arrayEscuelas = downloadedEscuelas
DispatchQueue.main.async {
print("id escuela actual:"+self.idEscuelaActual!+":)")
self.escuelaTextBox.text = self.arrayEscuelas[0].escuela!
self.idEscuelaActual = "\(self.arrayEscuelas[0].id_escuela!)" as String
}
downloadJsonAnuncios(id_escuela:("\arrayEscuelas[0].id_escuela!)"))
} catch let jsonErr {
print("Error: ", jsonErr)
}
}.resume()
默认情况下,viewDidLoad 中的代码在 UIThread 上同步运行。 您的 API 调用在单独的线程上 运行 并且允许您的其他方法在完成之前执行。 您可能应该在您的方法中使用完成处理程序,这样您的第二个方法只会在您的 api 调用完成后被调用。
查看此答案以实施 CompletionHandler