当我尝试重新加载日期时,Swift 5 TableView 在 ViewController 中发现 nil

Posted

技术标签:

【中文标题】当我尝试重新加载日期时,Swift 5 TableView 在 ViewController 中发现 nil【英文标题】:Swift 5 TableView found nil inside ViewController when i try to reloaddate 【发布时间】:2021-04-12 19:19:05 【问题描述】:

我正在从 API 端点获取数据,并且在第一次获取时 tableview 正在工作。

但是当我更改 API url 时,获取仍然有效,但对于 tableview,xcode 抛出“致命错误:在隐式展开可选值时意外发现 nil”错误消息。”

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource 
    
   
    @IBOutlet weak var tableView: UITableView!
    
    var listOfRecipes = [RecipeDetail]()
    
        didSet 
            DispatchQueue.main.async 
                self.tableView.reloadData() --->> Here i get the nil error
            
        
    
    
    override func viewDidLoad() 
        super.viewDidLoad()
        
        tableView.delegate = self
        tableView.dataSource = self
        
        callApi()
        
    
    
    func callApi() 
        print("------------------- API -------------------")
        print(ApiSettings.instance.apiEndpoint)
        //self.listOfRecipes.removeAll()
        let recipeRequest = RecipeRequest(url: ApiSettings.instance.apiEndpoint)
        recipeRequest.getData  result in
            switch result 
                case .failure(let error):
                    print(error)
                case .success(let recipes):
                    self.listOfRecipes = recipes
            
        
    
  
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
        return listOfRecipes.count
    
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        let recipe = listOfRecipes[indexPath.row]
        cell.textLabel?.text = recipe.title
        cell.detailTextLabel?.text = recipe.slug
        return cell
    


我还尝试从情节提要上的 tableview 中删除所有连接并再次添加它们,包括委托和数据源,但它仍然无法正常工作。第一次加载运行良好,但在应用程序崩溃之后。

我还检查了 listOfRecipes didSet,其中的数组包含来自第二个 API 查询的新值。

有人可能有什么建议吗?谢谢!

【问题讨论】:

我删除了我之前的评论,因为您在问题接近尾声时回答了它。但是,在哪一行代码中解包 nil 时会出现致命错误? 对不起,我扩展了我的描述。但是这里的 api 更改: var listOfRecipes = [RecipeDetail]() didSet DispatchQueue.main.async self.tableView.reloadData() --->> 这里我得到了 nil 错误 我在您的didSet 中看到的唯一可选值是tableView,这是一个隐式展开的可选值,所以它必须是nil。我看不到你在哪里设置它(可能在ViewController 的外部?),但我通常希望在viewDidLoad 中找到它。奇怪的是你在viewDidLoad 中设置了它的delegatedataSource。如果是nil,我希望你能先得到错误。 看起来有人为您找到了答案。我很高兴它成功了。 【参考方案1】:

在属性观察器中重新加载表视图不是一个好习惯。最有可能是因为第一次调用观察者时 table view outlet 还没有连接。

在 API 调用中重新加载它。

var listOfRecipes = [RecipeDetail]()


func callApi() 
    print("------------------- API -------------------")
    print(ApiSettings.instance.apiEndpoint)
    //self.listOfRecipes.removeAll()
    let recipeRequest = RecipeRequest(url: ApiSettings.instance.apiEndpoint)
    recipeRequest.getData  result in
        switch result 
            case .failure(let error):
                print(error)
            case .success(let recipes):
                DispatchQueue.main.async 
                   self.listOfRecipes = recipes
                   self.tableView.reloadData() 
                
        
    

【讨论】:

感谢您的建议,但我也遇到了同样的错误,就在主异步```case .success(let recipes): DispatchQueue.main.async self.listOfRecipes = recipes self. tableView.reloadData() --> 现在我得到了故事板上的 nil 错误 ``` 我还检查了 tableview 和数据源和委托是 ViewController.... 那么插座连接不正确和/或您实例化控制器的方式错误。 但是为什么它在第一次加载时工作?它正在从 callApi 函数中获取所有内容。并且插座也已连接。 你是对的,你的解决方案是有效的!我的问题导致了 SideMenu。感谢您的帮助!

以上是关于当我尝试重新加载日期时,Swift 5 TableView 在 ViewController 中发现 nil的主要内容,如果未能解决你的问题,请参考以下文章

关闭块不会在第二次 swift3 上重新加载表

重新加载 tableView 部分而不重新加载标题部分 - Swift

当我在 Xcode 11 中将 swift 4.2 转换为 swift 5 时继续加载

如何在 TableView 中重新加载数据

在节中重新加载标题而不在 swift 中重新加载节行

Swift数组追加不适用于collectionView重新加载数据