Tableview拖到底部时导致应用程序崩溃

Posted

技术标签:

【中文标题】Tableview拖到底部时导致应用程序崩溃【英文标题】:Tableview causes app to crash when dragged to the bottom 【发布时间】:2017-11-16 21:13:45 【问题描述】:

当滚动比表格视图中的最后一个帖子/项目更远时,应用程序崩溃并且我收到错误消息:“在展开可选值时意外发现 nil”。就像它试图找到另一个不存在的帖子一样,但我不知道为什么... tableview 中的帖子按应有的方式显示。

我认为这里有问题:

    func tableView(_ tableView: UITableView, cellForRowAt indexpath: IndexPath) -> UITableViewCell 

    let post = posts[indexpath.row]

    if let cell = tableView.dequeueReusableCell(withIdentifier: "PostCell", for: indexpath) as? PostCell
        cell.configureCell(post: post)

        return cell
     else 
        return PostCell()
    

(当我删除 else 部分时,我收到此错误:“在预期返回 'UITableViewCell' 的函数中缺少返回值)

var posts = [Post]()

配置单元:

func configureCell(post: Post) 

    self.post = post



    if post.altA.isEmpty == false 
        altALabel.text = post.altA["text"] as? String
        if let votes = post.altA["votes"]
            self.altAVotesLbl.text = "\(votes)"
        
     else 
        print("No data found in Alt A")
    

    if post.altB.isEmpty == false 
        altBLabel.text = post.altB["text"] as? String
        if let votes = post.altB["votes"]
            self.altBVotesLbl.text = "\(votes)"
        
     else 
        print("No data found in Alt B")
    

    if post.altD.isEmpty == false 
        altDLabel.text = post.altD["text"] as? String
        if let votes = post.altD["votes"]
            self.altDVotesLbl.text = "\(votes)"
        
     else 
        print("No data found in Alt D")
        altDView.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0)
        altDVotesView.removeFromSuperview()
        altDLabelView.removeFromSuperview()
    

    if post.altC.isEmpty == false 
        altCLabel.text = post.altC["text"] as? String
        if let votes = post.altC["votes"]
            self.altCVotesLbl.text = "\(votes)"
        
     else 
        print("No data found in Alt C")
        self.altCView.removeFromSuperview()
        self.botBtnsStackView.removeFromSuperview()
    



import Foundation

类帖子

private var _text: String!
private var _postKey: String!
private var _backgroundImg: Int!

private var _altA: Dictionary<String, Any>!
private var _altB: Dictionary<String, Any>!
private var _altC: Dictionary<String, Any>!
private var _altD: Dictionary<String, Any>!




//TEXT
var text: String 
    return _text


//BACKGROUND
var backgroundImg: Int
    return _backgroundImg


//POSTKEY
var postKey: String
    return _postKey



//ALTERNATIVES
var altA: Dictionary<String, Any> 
    return _altA


var altB: Dictionary<String, Any> 
    return _altB


var altC: Dictionary<String, Any> 
    return _altC


var altD: Dictionary<String, Any> 
    return _altD




init(postKey: String, postData: Dictionary<String, Any>) 
    self._postKey = postKey

    if let text = postData["text"]
        self._text = text as! String
     else 
        self._text = ""
    


     if let backgroundImg = postData["backgroundImg"]
        self._backgroundImg = backgroundImg as! Int
    



    if let altA = postData["altA"]
        self._altA = altA as! Dictionary<String, Any>
    

    if let altB = postData["altB"]
        self._altB = altB as! Dictionary<String, Any>
    


    if let altC = postData["altC"]
        self._altC = altC as! Dictionary<String, Any>
     else 
        let emptyDictionary = [String: Any]()
        self._altC = emptyDictionary
    


    if let altD = postData["altD"]
        self._altD = altD as! Dictionary<String, Any>
     else 
        let emptyDictionary = [String: Any]()
        self._altD = emptyDictionary
    

其余的tableview代码(没什么特别的):

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



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

【问题讨论】:

指出导致崩溃的确切代码行。 不需要else 部分。要么您拥有该单元并且它正在工作(即 dequed),要么您的单元处理存在严重错误。 当我删除 else 部分时,我收到此错误:“在预期返回 'UITableViewCell' 的函数中缺少返回” 我在 "cell.configureCell(post: post)" 处收到错误 "Unexpectedly found nil while unwrapping an Optional value" 显示postsconfigureCell 的声明。并将所有这些信息放在您的问题中,而不是在 cmets 中。 【参考方案1】:

对,所以问题是您要从 superview 中删除 self.altCView 和其他视图。

您必须记住,单元格是可重复使用的,因此每当它们离开屏幕时,它们就会“出列”并重复使用。

因此,如果一个单元格最初是一个 altD 单元格,并且您删除了所有其他超级视图,但随后它会作为 altC 单元格被重用。尝试设置标签会使应用程序崩溃,因为从超级视图中删除会从内存中释放它(如果您使用弱引用,由于某种原因这是 IBOutlet 的默认值。另一个提示,让您的所有 IBOutlets 强大我只是认为它更好)

一旦视图从超级视图中删除,它们就会永远消失,除非你重新添加它们,所以我会避免在多次运行的代码上这样做,比如cellForRowAtIndex

尝试将它们设置为隐藏(或将它们设置为 CGZero)(但同样,请注意单元格重复使用。假设您获得的单元格永远不会具有正确的值,因此如果您正在使用它们,请始终设置为不隐藏并且始终如果你不使用它们,则设置为隐藏。如果你确实需要它,忘记 setHidden = false 是一个常见的错误。它可能仍然隐藏在上次使用单元格时)

【讨论】:

【参考方案2】:

从超级视图中删除视图似乎不是一个好主意。我用 isHidden = true 替换了所有 removeFromSuperview() 方法,现在它不起作用了。

例如:altDLabelView.removeFromSuperview() 现在是 altDLabelView.isHidden = True

感谢您的帮助!

【讨论】:

以上是关于Tableview拖到底部时导致应用程序崩溃的主要内容,如果未能解决你的问题,请参考以下文章

刷新表格时应用程序崩溃(可能是tableView上的调用endUpdates导致崩溃)

tableView reloadData 导致应用在删除部分后崩溃

UITableView 在像 Facebook 应用程序一样滚动到底部时加载更多

Kotlin 协程协程异常处理 ④ ( Android 协程中出现异常导致应用崩溃 | Android 协程中使用协程异常处理器捕获异常 | Android 全局异常处理器 )

Kotlin 协程协程异常处理 ④ ( Android 协程中出现异常导致应用崩溃 | Android 协程中使用协程异常处理器捕获异常 | Android 全局异常处理器 )

获取的结果导致部分崩溃