UITableView - 意外发现 nil Swift

Posted

技术标签:

【中文标题】UITableView - 意外发现 nil Swift【英文标题】:UITableView - unexpectedly found nil Swift 【发布时间】:2021-05-19 22:28:38 【问题描述】:

我有问题。我有一个表格视图,我尝试从中填充一些 firebase 数据,但我的标签有错误。 “在隐式展开可选时意外发现 nil”。在控制台中,标签显示为 nil。我已经正确连接了我的 iboutlets,并且我已经在检查器中设置了“reuseIdentifier”。我正在使用原型单元。

我的全班:

struct Info 
    var address: String
    var name: String
    var phoneNumber: String
    


class InfoViewController: UITableViewController

    let cellReuseIdentifier = "cell"
    
    var info: [Info] = []
    
    override func viewDidLoad() 
        super.viewDidLoad()
        getCartProducts()
        self.tableView.register(InfoTableViewCell.self, forCellReuseIdentifier: cellReuseIdentifier)
        
        navigationItem.title = "Profilul meu"
        
        
        
    
    func getCartProducts() 
        
        let db = Firestore.firestore()
        let userID = (Auth.auth().currentUser?.uid)!
        db.collection("Users").document(userID).getDocument  (document, error) in
            if let error = error 
                print(error)
                return
             else 
                if let  document = document 
                    let data = document.data()
                    let newEntry = Info(address: data!["address"] as! String, name: data!["name"] as! String , phoneNumber: data!["phoneNumber"] as! String
                    )
                    
        
                    self.info.append(newEntry)
                
            
            
            DispatchQueue.main.async 
                //  self.datas = self.filteredData
                self.tableView.reloadData()
            
            
        
    
    
    
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
        return info.count
        
    
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
        let cell = tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier, for: indexPath) as! InfoTableViewCell
        let infos = info[indexPath.row]
        cell.numeL.text = infos.name
        cell.adresaL.text = infos.address
        cell.telefonL.text = infos.phoneNumber
        
        return cell
    
    
    
    
    


还有我的 Cell 课程,如果这也有帮助的话:

class InfoTableViewCell: UITableViewCell 

    
    @IBOutlet weak var adresaL: UILabel!
    @IBOutlet weak var numeL: UILabel!
    @IBOutlet weak var telefonL: UILabel!
    override func awakeFromNib() 
        super.awakeFromNib()
        // Initialization code
    

    override func setSelected(_ selected: Bool, animated: Bool) 
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    


错误在:

 cell.numeL.text = infos.name
        cell.adresaL.text = infos.address
        cell.telefonL.text = infos.phoneNumber

【问题讨论】:

使用!as! 解包本质上是危险的,并且可能导致此崩溃。查看您使用它的所有地方并学习使用if letguard let(“可选绑定”)来处理您可能拥有nil 值的情况。 docs.swift.org/swift-book/LanguageGuide/TheBasics.html 在 Firebase 闭包中不需要DispatchQueue.main.async ; UI 调用总是在主线程上完成。在从 firebase 加载数据并刷新 tableView 之前,也要这样做self.tableView.register(InfoTableViewCell.self, forCellReuseIdentifier: cellReuseIdentifier) 【参考方案1】:

如果您使用原型单元格,则必须没有 tableView.register 代码。删除它。

仔细检查情节提要中的表格视图控制器检查器。确保它具有正确的类。

然后在情节提要中检查其原型单元检查器。确保它具有正确的类。然后确保它有正确的标签出口。

【讨论】:

它有正确的类并且单元格的身份检查器也是正确的。真的不知道怎么了。。【参考方案2】:

代替

let newEntry = Info(address: data!["address"] as! String, name: data!["name"] as! String , phoneNumber: data!["phoneNumber"] as! String)

你必须使用这样的东西

guard let address = data?["address"] as? String else return
guard let  name = data?["name"] as? String else return
guard let phoneNumber = data?["phoneNumber"] as? String else return
let newEntry = Info(address: address, name: name , phoneNumber: phoneNumber)

此方法将安全地解包您的数据,但请记住,如果它们中的每一个都为 null,您将没有任何数据,因此最好在 firebase 数据库中设置默认值以避免该问题

也适用于您的表格视图功能 而不是

let cell = tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier, for: indexPath) as! InfoTableViewCell

使用

 guard let cell = tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier, for: indexPath) as? InfoTableViewCell else return UITableViewCell()

在这种情况下,您的单元格标识符不正确,您的应用至少不会崩溃

【讨论】:

【参考方案3】:

您需要正确注册单元格

self.tableView.register(UINib(nibName:"InfoTableViewCell", bundle: nil), forCellReuseIdentifier: cellReuseIdentifier)

在此处设置标识符

【讨论】:

感谢您的回答,使用您的代码时出现以下错误:无法在捆绑中加载 NIB: 你有InfoTableViewCell.xib 吗?还是表格内的单元格?如果在表格内,则完全删除寄存器行 我正在使用原型单元。我试图删除注册行,但出现错误:“无法将具有标识符单元格的单元格出列 - 必须为标识符注册一个 nib 或一个类” 已设置,但仍然出现错误,单元类也设置正确【参考方案4】:

我已经解决了这个问题。我使用了一个 .xib 文件,现在正在工作。真的不知道为什么它不适用于原型单元。

【讨论】:

以上是关于UITableView - 意外发现 nil Swift的主要内容,如果未能解决你的问题,请参考以下文章

removeFromSuperView() 和单元格 = 致命错误:在展开可选值时意外发现 nil

Swift:意外发现 nil [重复]

value 不是 nil,而是在展开 Optional 值时意外发现 nil

Swift transitionCoordinator() 意外发现 nil 错误

使用 userDefaults 时意外发现 nil

HealthKit(打开可选时意外发现 nil)