大家好,我在线学习这门课程,并且有类似的功能。
typealias DownloadCompleted = () -> ()
var pokemonId = 0
func fetchPokemon(url: String, completed: @escaping DownloadCompleted) {
let context = coreData.persistentContainer.viewContext
let url = URLRequest(url: URL(string: url)!)
let task = URLSession.shared.dataTask(with: url) { (data, repsonse, error) in
if error != nil {
print(error!)
}
do {
let jsonResult = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! NSDictionary
let jsonArray = jsonResult.value(forKey: "results") as! [[String: Any]]
for pokemonData in jsonArray {
self.pokemonId += 1
if self.pokemonId > 721 {
self.coreData.saveContext()
return
}
guard let name = pokemonData["name"] as? String else {
return
}
let pokemon = Pokemon(context: context)
pokemon.name = name
pokemon.id = self.pokemonId
print("Name: \(pokemon.name) Id:\(self.pokemonId)")
}
guard let nextURL = jsonResult.value(forKey: "next") as? String else {
return
}
DispatchQueue.main.async {
self.fetchPokemon(url: nextURL, completed: {
})
}
completed()
} catch let err {
print(err.localizedDescription)
}
}
task.resume()
}
一旦函数解析完数据,我就试图设置一个等于721 Pokemon的数组。我真的不明白完成的()是如何工作的。我希望完成解析721后完成调用。然而在我的情况下,它会在第一个20口袋妖怪之后被调用。有人可以帮我理解完成的()是如何工作的。
欢迎任何有关其工作原理的帮助,链接或文章。谢谢:))
答案 0 :(得分:0)
我不确定我是否正确理解了您的问题,但是如果您希望在为721 Pokemon完成解析后执行completed()块。
当条件> = 721时,调用done()阻止for循环尝试更改您的代码,如下所示
for pokemonData in jsonArray {
self.pokemonId += 1
if self.pokemonId > 721 {
self.coreData.saveContext()
completed()
return
}
guard let name = pokemonData["name"] as? String else {
return
}
let pokemon = Pokemon(context: context)
pokemon.name = name
pokemon.id = self.pokemonId
print("Name: \(pokemon.name) Id:\(self.pokemonId)")
}