ios - 当 TableView 单元格被选择两次时,它会崩溃并出现意外的 nil 错误

标签 ios swift uitableview

本质上,我有一个 TableView Controller ,其中的单元格由 JSON 数据填充。当用户选择单元格时,应该打开一个不同的 View Controller ,其中包含有关所选单元格的更多信息。

我使用用户默认值来传递有关所选单元格的信息以及 POST 请求中检索数据所需的信息。

问题是当选择一个单元格时,我有时会收到错误,发现意外的 nil。

这通常发生在选择单元格、呈现不同的 View Controller 、我返回表格 View 并选择相同的单元格时。

我相信这个问题与 dequeueReusableCell 有关,因为我注意到使用 fetchJSON 重新加载 viewDidAppear 中的 tableview 数据会降低发现错误的机会。

如果没有这个更改,错误就会一直发生。

import UIKit



class ScheduleCell: UITableViewCell {

    @IBOutlet weak var cellStructure: UIView!
    @IBOutlet weak var testingCell: UILabel!
    @IBOutlet weak var pickupLabel: UILabel!
    @IBOutlet weak var deliveryLabel: UILabel!

}

 class ScheduleTableViewController: UITableViewController {
    @IBOutlet weak var dateLabel: UIBarButtonItem!
    var driverName = UserDefaults.standard.string(forKey: "name")!
    var structure = [ScheduleStructure]()
    var pickupTitle = ""
    override func viewDidLoad() {
        super.viewDidLoad()



        fetchJSON()
        let refreshControl = UIRefreshControl()
        refreshControl.addTarget(self, action: #selector(doSomething), for: .valueChanged)
        tableView.refreshControl = refreshControl


    }

    private func fetchJSON() {
        guard let url = URL(string: "https://example/example/example.php"),
            let value = driverName.addingPercentEncoding(withAllowedCharacters: .urlQueryValueAllowed)
            else { return }

        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        request.httpBody = "driverName=\(value)".data(using: .utf8)

        URLSession.shared.dataTask(with: request) { data, _, error in
            guard let data = data else { return }


            do {
                self.structure = try JSONDecoder().decode([ScheduleStructure].self,from:data)
                DispatchQueue.main.async {
                    self.tableView.reloadData()
                }
            }
            catch {
                print(error)
            }

            }.resume()

    }






        override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

            return structure.count
    }


        override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {


            let cell = tableView.dequeueReusableCell(withIdentifier: "customerID", for: indexPath) as! ScheduleCell



            cell.textLabel?.font = .boldSystemFont(ofSize: 18)
            cell.textLabel?.textColor = UIColor.clear

            let portfolio = structure[indexPath.row]
            //cell.textLabel?.text = portfolio.customer


            cell.pickupLabel.layer.cornerRadius = 10
            cell.pickupLabel.clipsToBounds = true

            return cell

        }
    override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
        return self.tableView(tableView, heightForRowAt: indexPath)
    }

        override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {


            let cell = tableView.dequeueReusableCell(withIdentifier: "customerID", for: indexPath) as! ScheduleCell
            //cell.cellStructure.layer.cornerRadius = 50
            let portfolio = structure[indexPath.row]
            let controller = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "deliveryController")


            pickupTitle = portfolio.customer
            UserDefaults.standard.set(pickupTitle, forKey: "TitleText")
            controller.navigationItem.title = pickupTitle
            let navigationController = UINavigationController(rootViewController: controller)

            self.present(navigationController, animated: true, completion: nil)

        }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)


    }

        override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
            return 160.0
        }
        override func viewWillAppear(_ animated: Bool) {

        fetchJSON()


        }


}

最佳答案

这可能是因为当您返回 View 时,tableView 需要时间再次重新加载数据,这就是为什么您得到 nil 的原因。 在 fetchJSON() 中尝试这个

 do {
DispatchQueue.main.async {
            self.structure = try JSONDecoder().decode([ScheduleStructure].self,from:data)
                self.tableView.reloadData()
            }
    }

关于ios - 当 TableView 单元格被选择两次时,它会崩溃并出现意外的 nil 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56598406/

相关文章:

ios - UITableView 中的 UIScrollView 中的 ContentOffset 问题

ios - firebaseui-ios FirebaseTableViewDataSource 与 UITableView 同步

ios - 使用 iOS 核心电话框架进行通话录音

ios - Objective-C prepareForSegue 问题

Swift - Case 语句和 MetaType 检查?

ios - UItableView 中的 UICollectionView 只获取空的 tableview,我错过了什么?

ios - 如何使用字典数组 iOS swift 解析 JSON

ios - 在 View Controller 之间切换时图像旋转动画速度加快?

ios - Swift 数组 : Keeping the order while filtering an array using another

c# - Xamarin C# 一个 UITableView 中的两个 UITableViewCells