Swift 3逃逸关闭变化不粘滞
我正在尝试使用OMDb API编写一个权力游戏的情节概要。我从服务器上获得的信息很好,但是我很难将这些数据发送到我的UITableView 这既是调用闭包的函数,也是定义闭包的函数:Swift 3逃逸关闭变化不粘滞,swift,multithreading,closures,Swift,Multithreading,Closures,我正在尝试使用OMDb API编写一个权力游戏的情节概要。我从服务器上获得的信息很好,但是我很难将这些数据发送到我的UITableView 这既是调用闭包的函数,也是定义闭包的函数: func getAllForSeason(season: Int) { let uri = "\(baseURL)\(urlId)&season=\(season)" var episodeList = [EpisodeModel]() let url = URL(string: u
func getAllForSeason(season: Int) {
let uri = "\(baseURL)\(urlId)&season=\(season)"
var episodeList = [EpisodeModel]()
let url = URL(string: uri)
let task = URLSession.shared.dataTask(with: url!) { (data, response, error) in
if error != nil {
print("Error retrieving information. No season found")
} else {
if let content = data {
do {
let seasonJSON = try JSONSerialization.jsonObject(with: content, options: .mutableContainers) as? [String: Any]
let episodesFound = seasonJSON?["Episodes"] as! [[String: String]]
for episodeJSON in episodesFound {
let number = Int(episodeJSON["Episode"] ?? "0") ?? 0
var episodeToAdd = EpisodeModel()
self.getTemporaryEpisode(season: season, number: number, completion: {(result:EpisodeModel) in
episodeToAdd = result
print(episodeToAdd.season)
})
print(episodeToAdd.season)
episodeList.append(episodeToAdd)
}
DispatchQueue.main.async {
self.delegate?.didGetSeason(episodes: episodeList)
}
} catch {
print ("Error retrieving information. No seasons found")
}
}
}
}
task.resume()
}
private func getTemporaryEpisode(season: Int, number: Int, completion: @escaping(_ response:EpisodeModel)->Void) {
let episode = EpisodeModel()
let uri = "\(baseURL)\(urlId)&season=\(season)&episode=\(number)"
let url = URL(string: uri)
let task = URLSession.shared.dataTask(with: url!) { (data, response, error) in
if error != nil {
print("Error downloading episode information. Empty Episode returned")
} else {
if let content = data {
do {
let episodeJSON = try JSONSerialization.jsonObject(with: content, options: JSONSerialization.ReadingOptions.mutableContainers) as? [String: Any]
episode.title = (episodeJSON?["Title"] as? String)?.description ?? ""
let dateString = (episodeJSON?["Released"] as? String)?.description ?? ""
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy MMM dd"
episode.releaseDate = dateFormatter.date(from: dateString) ?? Date()
episode.rating = (episodeJSON?["Rated"] as? String)?.description ?? ""
episode.season = Int(episodeJSON?["Season"] as? String ?? "") ?? 0
episode.number = Int(episodeJSON?["Episode"] as? String ?? "") ?? 0
let runtimeString = (episodeJSON?["Runtime"] as? String)?.description ?? "0 min"
let spaceIndex = runtimeString.index(of: " ") ?? runtimeString.endIndex
let minuteString = runtimeString[runtimeString.startIndex..<spaceIndex]
episode.minutes = Int(minuteString) ?? 0
episode.director = (episodeJSON?["Director"] as? String)?.description ?? ""
episode.writer = (episodeJSON?["Writer"] as? String)?.description ?? ""
let actorsString = (episodeJSON?["Actors"] as? String)?.description ?? ""
episode.actors = actorsString.components(separatedBy: ", ")
episode.plot = (episodeJSON?["Plot"] as? String)?.description ?? ""
} catch {
print("Error downloading episode information. Empty or incomplete episode returned")
}
}
}
completion(episode)
}
task.resume()
}
func getAllForSeason(季节:Int){
let uri=“\(baseURL)\(urlId)&季节=\(季节)”
变量eposodelist=[eposodemodel]()
让url=url(字符串:uri)
让task=URLSession.shared.dataTask(带:url!){(数据、响应、错误)在
如果错误!=nil{
打印(“检索信息时出错。未找到季节”)
}否则{
如果让内容=数据{
做{
让季候JSON=尝试JSONSerialization.jsonObject(使用:content,options:.mutableContainers)作为?[String:Any]
让EpicodeFound=seasonJSON?[“剧集”]作为![[String:String]]
对于EpiodesFind中的EpiodesJSON{
设number=Int(eposodejson[“插曲”]??“0”)
var EpiodeToAdd=EpiodeModel()
getTemporarySpidence(季节:季节,编号:编号,完成:{(结果:eposodemodel))在
eposodeadd=结果
印刷品(第二季)
})
印刷品(第二季)
eposodelist.append(eposodetoadd)
}
DispatchQueue.main.async{
self.delegate?.didGetSeason(剧集:插曲集)
}
}抓住{
打印(“检索信息时出错,未找到季节”)
}
}
}
}
task.resume()
}
private func GetTemporarySpidence(季节:Int,编号:Int,完成:@escaping(u响应:epiodeModel)->Void){
让插曲=插曲模型()
let uri=“\(baseURL)\(urlId)&季节=\(季节)&插曲=\(数字)”
让url=url(字符串:uri)
让task=URLSession.shared.dataTask(带:url!){(数据、响应、错误)在
如果错误!=nil{
打印(“下载剧集信息时出错。返回空剧集”)
}否则{
如果让内容=数据{
做{
让eposodejson=try JSONSerialization.jsonObject(with:content,options:JSONSerialization.ReadingOptions.mutableContainers)作为?[String:Any]
eposion.title=(eposodejson?[“title”]作为?字符串)?。说明??“
让dateString=(eposodeJSON?[“已发布”]作为?字符串)?。说明??“
让dateFormatter=dateFormatter()
dateFormatter.dateFormat=“yyyy MMM dd”
eposion.releaseDate=dateFormatter.date(from:dateString)??日期()
eposion.rating=(eposodejson?[“Rated”]为?字符串)?。说明??“
eposion.seasure=Int(eposodejson?[“seasure”]作为?字符串??)?0
eposition.number=Int(eposodejson?[“eposition”]作为?字符串??)?0
让runtimeString=(eposodeJSON?[“运行时”]作为?字符串)?。说明??“0分钟”
让spaceIndex=runtimeString.index(of:)??runtimeString.endIndex
让minuteString=runtimeString[runtimeString.startIndex..您的函数gettemporaryeposit
是异步的,因此您可以使用一组空片段通知代理
然后重新分配epiodeToAdd
变量以引用正确设置的插曲,但这对epiodeList
的内容没有任何影响。您可能希望等待填充epiodeList
,直到检索到正确的内容。您可以使用DispatchGroup
进行此操作
但是,如果您只是使用一个调度组
,则不需要按照预期的顺序返回剧集,因为它们将在同一时间单独请求。最简单的解决方案是将它们收集在一个数组中,然后在通知您的代表之前按剧集编号对数组进行排序。抱歉,尚未看到但是,粗略地看一下,您似乎建议每次调用getTemporarySpoint
都应该在类似dispatchGroup.enter()
,以及dispatchGroup.leave()
的内容之后,然后在我的完成闭包中调用dispatchGroup.wait()
在循环结束时。如果这是正确的,我可以将其附加到我在附件中发送回的列表中,然后在循环完成后,在通知我的代表之前对数组进行排序。是的,您对调度组的想法是正确的。关键是循环将在任何getTemporaryEpisod之前完成e
调用调用它们的完成处理程序。您需要使用DispatchGroup.wait()
阻止代码继续,直到所有完成处理程序都返回为止。