我有一个请求任务,其中有一个与另一个请求任务的循环。我想完成循环请求任务,然后继续完成另一个。
let dispatchGroup = DispatchGroup()
override func viewDidLoad() {
super.viewDidLoad()
tableView.reloadData()
fetchData()
dispatchGroup.notify(queue: .main) {
self.tableView.reloadData()
}
}
func fetchData() {
var movies: String?
dispatchGroup.enter()
print("Enter fetchData")
let task = session.dataTask(with: url) { data, response, error in
if error != nil || data == nil {
print("Client error!")
return
}
guard let response = response as? HTTPURLResponse, (200...299).contains(response.statusCode) else {
print("Server error!")
return
}
guard let mime = response.mimeType, mime == "application/json" else {
print("Wrong MIME type!")
return
}
do {
let json = try JSONSerialization.jsonObject(with: data!, options: []) as? [String : Any]
if let result = json?["results"] as? Array<Dictionary<String, Any>> {
for results in result {
self.char = StarWarsData.init(name: results["name"] as! String, height: results["height"] as! String, mass: results["mass"] as! String, gender: results["gender"] as! String, birthyear: results["birth_year"] as! String, film: results["films"] as! [String])
let name = self.char.name
let height = self.char.height
let mass = self.char.mass
let gender = self.char.gender
let birthyear = self.char.birthyear
let charFilms = self.char.film
for theFilms in charFilms {
self.fetchFilms(films: theFilms) { (filmNames) in
movies = filmNames
print(movies!)
}
}
let item = StarWarsData(name: name, height: height, mass: mass, gender: gender, birthyear: birthyear, film: charFilms)
self.dataArray.append(item)
self.dataNames.append(name)
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
}
}catch {
print("JSON error: \(error.localizedDescription)")
}
print("Leaving fetchData")
self.dispatchGroup.leave()
}
task.resume()
}
func fetchFilms(films: String, taskCallBack: @escaping (String) -> ()) {
let url = URL(string: films)!
var filmsArr: [String] = []
var item: String!
var joinItem: String!
dispatchGroup.enter()
print("Enter fetchFilms")
let task = self.session.dataTask(with: url, completionHandler: { (data, response, error) -> Void in
if error != nil || data == nil {
print("Client error!")
return
}
guard let response = response as? HTTPURLResponse, (200...299).contains(response.statusCode) else {
print("Server error!")
return
}
guard let mime = response.mimeType, mime == "application/json" else {
print("Wrong MIME type!")
return
}
do {
let json = try JSONSerialization.jsonObject(with: data!, options: []) as? [String : Any]
if let results = json?["title"] as? String {
for results in results {
item = String(results)
filmsArr.append(item)
}
joinItem = filmsArr.joined(separator: "")
taskCallBack(joinItem)
}
}catch {
print("JSON error: \(error.localizedDescription)")
}
print("Leaving fetchFilms")
self.dispatchGroup.leave()
})
task.resume()
}
所以检查一下打印语句,你就会明白我想要什么。 这是我的输出:
Enter fetchData
Enter fetchFilms
Enter fetchFilms
Enter fetchFilms
Enter fetchFilms
Enter fetchFilms
Enter fetchFilms
Enter fetchFilms
Enter fetchFilms
Enter fetchFilms
Enter fetchFilms
Leaving fetchData
A New Hope
Leaving fetchFilms
The Empire Strikes Back
Leaving fetchFilms
Return of the Jedi
Leaving fetchFilms
The Force Awakens
Leaving fetchFilms
Revenge of the Sith
Leaving fetchFilms
The Empire Strikes Back
Leaving fetchFilms
The Phantom Menace
Leaving fetchFilms
Attack of the Clones
Leaving fetchFilms
Revenge of the Sith
Leaving fetchFilms
The Phantom Menace
Leaving fetchFilms
Notify table reloaded
我就是想要这个:
Enter fetchData
Enter fetchFilms
Enter fetchFilms
Enter fetchFilms
Enter fetchFilms
Enter fetchFilms
Enter fetchFilms
Enter fetchFilms
Enter fetchFilms
Enter fetchFilms
Enter fetchFilms
A New Hope
Leaving fetchFilms
The Empire Strikes Back
Leaving fetchFilms
Return of the Jedi
Leaving fetchFilms
The Force Awakens
Leaving fetchFilms
Revenge of the Sith
Leaving fetchFilms
The Empire Strikes Back
Leaving fetchFilms
The Phantom Menace
Leaving fetchFilms
Attack of the Clones
Leaving fetchFilms
Revenge of the Sith
Leaving fetchFilms
The Phantom Menace
Leaving fetchFilms
Leaving fetchData
Notify table reloaded
我想以某种方式在打印语句
Leaving fetchData
之前暂停任务并完成func fetchFilms
的整个过程,然后继续打印语句Leaving fetchData
。实际上func fetchData()
在func fetchFilms
结束之前就完成了,我没有拍我想要的电影。顺便说一句,print(movies!)
声明给了我电影,但为时已晚。
[编辑]:为了突出中篇文章的主要思想,还删除了信号量,这并不是真正的快速风格。
如果您希望一个函数在另一个函数调用之前完成(特别是在数据任务的情况下),您可以使用操作。
我找到了一篇更好的文章来指导您如何实现它。 https://medium.com/@oleary.audio/simultaneous-asynchronous-calls-in-swift-9c1f5fd3ea32