首页 > 解决方案 > 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”,或者在打印“cell for item at”之前的“got gifs”,并且引发了索引超出范围错误。

标签: swiftuikiturlsession

解决方案


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


推荐阅读