【问题标题】:Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value in "self.tableView.realoadData()"致命错误:在“self.tableView.realoadData()”中隐式展开可选值时意外发现 nil
【发布时间】:2021-03-22 09:57:16
【问题描述】:

我提出了 API 请求并想将其添加到表视图中。是否在加载数据之前调用了 reloadData()? tableView 存在问题,因为 API 调用工作正常。下面是代码:

class ViewController: UIViewController {

var tableView : UITableView!
var listOfHolidays = [HolidayDetails](){
    didSet{
        DispatchQueue.main.async{
            self.tableView.reloadData()
            self.navigationItem.title = "\(self.listOfHolidays.count) Holidays found"
        }
    }
}

在 ViewDidLoad 中调用 Fetch 函数。

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.
    DataFetch { (holidaydetails) in
        for items in holidaydetails{
            self.listOfHolidays.append(items)
            print(items)
        }
    
    }
}

API 调用的 Fetch 函数。

func DataFetch(completionHandler : @escaping ([HolidayDetails]) -> Void){
    guard let url = URL(string: "https://holidayapi.com/v1/holidays?   pretty&country=IN&year=2020&key=457d9815-2e0a-4140-9515-0f6ef0d5f8b9") else{return(print("Error"))}
    
    let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
        
        guard let data = data else{ return print("Error")}
        do{
            let holidayData = try JSONDecoder().decode(Holidays.self, from: data)
            let holidayDetail = holidayData.holidays
            completionHandler(holidayDetail)
        }
        catch{
            let error = error
            print(error.localizedDescription)
        }
    }
    task.resume()
}
}

扩展:

extension ViewController : UITableViewDataSource,UITableViewDelegate {

  func numberOfSections(in tableView: UITableView) -> Int {
      return 1
  }

  func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
      return listOfHolidays.count
  }

  func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
      let cell = tableView.dequeueReusableCell(withIdentifier: "cell",for: indexPath)
      let holidays = listOfHolidays[indexPath.row]
      cell.textLabel?.text = holidays.name
      cell.detailTextLabel?.text = holidays.date
      return cell
  }

}

我还有另一个带有数据模型的文件:

import Foundation

struct Holidays : Codable {
   var holidays : [HolidayDetails]
}
struct HolidayDetails : Codable {
   var name : String
   var date : String
}

【问题讨论】:

  • tableView 为零。它在情节提要中连接吗?否则,myViewController.listOfHolidays = 行在哪里?可能是您在加载 tableView 之前访问它,因为 didSet if listOfHolidays。
  • tableView 是 nil。你期待什么?

标签: swift xcode api uitableview


【解决方案1】:

正如@Larme 评论的那样,问题很可能出在您的didSet oberserver 中。 在某处,您将 listOfHolidays 设置为一个值 before 该控制器的视图确实加载了,例如在tableView 插座连接到UITableView 之前。 从 setter 中更新 UI 并不总是一个好主意。但是如果你真的想要它,你可以通过检查 tableView 是否为nil 来规避崩溃:

var listOfHolidays = [HolidayDetails](){
    didSet{
        guard self.tableView != nil else { return } 
        DispatchQueue.main.async{
            self.tableView.reloadData()
            self.navigationItem.title = "\(self.listOfHolidays.count) Holidays found"
        }
    }
}

这段代码应该没有重载问题:如果tableView 是nil,reloadData 将不会被调用,但这没关系,因为一旦连接出口(@98​​7654329@ 之前) ,它会自行触发重新加载。

【讨论】:

    【解决方案2】:

    您的 tableView 为零:var tableView : UITableView!

    你只需要初始化它,例如这样:var tableView = UITableView()

    另外,您刚刚了解到使用 ! 并不是一个好习惯。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-01-26
      • 1970-01-01
      • 1970-01-01
      • 2016-02-29
      • 2020-09-19
      相关资源
      最近更新 更多