Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 3逃逸关闭变化不粘滞_Swift_Multithreading_Closures - Fatal编程技术网

Swift 3逃逸关闭变化不粘滞

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

我正在尝试使用OMDb API编写一个权力游戏的情节概要。我从服务器上获得的信息很好,但是我很难将这些数据发送到我的UITableView

这既是调用闭包的函数,也是定义闭包的函数:

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()
阻止代码继续,直到所有完成处理程序都返回为止。