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