当滚动到比表视图中的最后一个帖子/项目更远的位置时,该应用程序崩溃,并且我收到错误消息:“在展开一个可选值时意外发现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


类Post {

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
}

最佳答案

正确,所以问题在于您正在从超级视图中删除self.altCView和其他视图。

您必须记住,单元是可重用的,因此,只要它们离开屏幕,它们就会“出队”并重新使用。

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

一旦视图从超级视图中删除,除非您重新添加视图,否则它们将永远消失,因此,我将避免在运行多次的代码(如cellForRowAtIndex)上执行此操作

尝试将它们设置为隐藏(或将帧设置为CGZero)(但再次提请注意单元格重用。假设您获得的单元格永远没有正确的值,因此如果使用它们,请始终将其设置为非隐藏,并始终将其设置为hidden如果您不使用它们,这是一个常见的错误,如果您确实需要它,则忘记设置setHidden = false。它可能仍在上次使用该单元格时被隐藏了)

10-05 20:06