Tableview会导致应用在拖动到底部时崩溃

时间:2017-11-16 21:13:45

标签: ios swift uitableview

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

class 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
}

2 个答案:

答案 0 :(得分:0)

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

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

感谢您的帮助!

答案 1 :(得分:0)

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

你必须记住,细胞是可重复使用的,所以每当它们离开屏幕时,它们就会“出列”并重复使用。

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

一旦从superview中删除了视图,除非你重新添加它们,否则它们将永远消失,所以我会避免在运行多次的代码上执行此操作,例如cellForRowAtIndex

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