Swift / UIKit- URLSession.shared.dataTask不执行completionHandler

问题描述

因此,我对Swift还是比较陌生,一直试图找到解决方案,但无济于事。异步代码尤其让我头疼。我最近大概一个月后才回到这个项目,却没有碰到它,我发誓这段代码已经事先可以正常工作。

我正在使用UITabBarController的viewDidLoad方法向本地服务器发出GET请求。我可以看到服务器接收到请求并输出JSON,所以我知道这不是问题。 UITabBarController包含两个UICollectionViewController,它们在其cellForItemAt方法中引用了此请求的数据,但是由于在请求完成之前执行它们,因此抛出了错误

尽管请求本身具有完成处理程序,而包含该请求的方法具有转义的完成处理程序,但我的代码继续执行而不是等待它们,我不知所措。任何建议将不胜感激。这是我的代码,简而言之:

class TabViewController: UITabBarController {

    override func viewDidLoad() {
        super.viewDidLoad()

        GifController.getGifs(forDate: date){(gifs) in
               
                print("completion handler")
        }
}

class GifController{

static func getGifs(forDate date: Date,completionHandler: @escaping ([Gif]) -> Void){
//generates request
let task = URLSession.shared.dataTask(with: request) { (data,response,error) in
            
    print("eyyyyyy")

    if let data = data{
       //JSON logic
                
     do{
          let gifs = try decoder.decode(Array<Gif>.self,from: data)
                    
          print("Got \(gifs.count) gifs")
                    
          completionHandler(gifs)
                    
      }
     catch{
           print(error)
     }

   }
}
        task.resume()
}


class GifCollectionViewController: UICollectionViewController {

override func collectionView(_ collectionView: UICollectionView,cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellReuseIdentifier,for: indexPath) as! GifCollectionViewCell
        
        let index = indexPath.item
        
        print("cell for item at")
        
        //this instance variable is being written in the UITabBarController's viewDidLoad. It's throwing an index out of range error
        let gif = self.gifs[index]
 }
}

不会打印来自TabViewController的“完成处理程序”,也不会打印来自GifController的“ eyyyy”,也不会打印“项目所在的单元格”并抛出索引超出范围错误之前的“ get gifs”。>

解决方法

我自己解决了这个问题。我在cellForItemAt方法中添加了对空数组的检查,然后在TabViewController的完成处理程序中异步将主视图上的CollectionView重新加载。