为什么我的值没有传递给secondViewController

时间:2017-05-07 14:29:09

标签: ios json swift swift3 segue

我想将简单的String从oneVC传递给secondVC。我是iOS新手。

  1. 我声明了String nameOfFilm。
  2. 当我点击CollectionViewItem时,我正在下载JSON,取一个值(String)并将其分配给nameOfFilm。然后我开始segue到第二个VC。
  3. 具有正确标识符的PrepareForSegue方法中的
  4. 我将secondVC值与nameOfFlim进行比较。(nextScene.name = nameOfFilm)
  5. 在结果中,当第二个VC进入时,nextScene.name为空。此处的图像描述 我正确解析了JSON。我认为它可能在时间上不匹配,而且某些功能太快了。是什么导致了这个问题?

    var nameOfFilm = String()
    
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        INDEX_NUMBER_BEFORE = indexPath.row
        let filmID = arrayWithID[INDEX_NUMBER_BEFORE]
        downloadFilm(url: "https://api.themoviedb.org/3/movie/\(filmID)\(key)&append_to_response=videos,images")
        performSegue(withIdentifier: "toTheDetail", sender: self)
    }
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "toTheDetail" {
            let nextScene = segue.destination as! FilmDetailViewController
            nextScene.name = nameOfFilm
        }
    }
    

1 个答案:

答案 0 :(得分:1)

这里的问题是downloadFilm将是一个在后台发生的异步任务,需要一些时间来发出请求并使用您需要的值进行响应。

您的downloadFilm函数应接受回调,以便您可以等待响应值,然后根据该响应执行操作,使用它的典型方法如下:

downloadFilm(url: "https://api.themoviedb.org/3/movie/\(filmID)\(key)&append_to_response=videos,images") { filmName in 
    self.nameOfFilm = filmName
    self.performSegue(withIdentifier: "toTheDetail", sender: self)
}

要做到这一点,你需要更新你的downloadFilm函数,以便它类似于...

func downloadFilm(url: String, completion: @escaping (_ filmName: String) -> Void) {
   // do work here to setup network request
   let task = URLSession.shared.dataTask(with: request) { data, response, error in
      // parse response and get name
      completion(name)
   }
}

Here是Swift完成处理程序的指南,有助于理解这个概念。