EXC_BAD_ACCESS 在 heightForRowAt 内时

Posted

技术标签:

【中文标题】EXC_BAD_ACCESS 在 heightForRowAt 内时【英文标题】:EXC_BAD_ACCESS when inside heightForRowAt 【发布时间】:2017-09-15 03:09:24 【问题描述】:

我正在尝试使用以下代码创建可扩展的 UITableViewCells:

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat 
    let cell = tableView.cellForRow(at: indexPath) as! feedBaseCell

    if cell.expandButton.isExpanded == true 
        return 128
     else 
        return 64
    
    return 64

.isExpanded 是 feedBaseCell 的自定义属性。当我运行此代码时,let cell = tableView.cellForRow(at: indexPath) as! feedBaseCell 行出现 EXC_BAD_ACCESS 错误。如何检查 .isExpanded 属性并根据它是真还是假返回高度?为什么我的代码不起作用?

编辑:cellForRowAtnumberOfRowsInSection 的代码:

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 

    return 3


func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
    let cell = tableView.dequeueReusableCell(withIdentifier: "feedBaseCell") as! feedBaseCell

    cell.backgroundColor = .clear
    cell.selectionStyle = UITableViewCellSelectionStyle.none
    cell.contentView.isUserInteractionEnabled = false

    cell.expandButton.tag = indexPath.row
    cell.expandButton.addTarget(self, action: #selector(self.expandTheCell(_:)), for: .touchUpInside)
    cell.contentView.bringSubview(toFront: cell.expandButton)

    return cell

这里是expandTheCell 方法:

func expandTheCell(_ sender: UIButton) 
    if sender.isExpanded == false 
        UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations: 
            sender.transform = sender.transform.rotated(by: .pi/2)
            sender.isExpanded = true
        , completion: nil)
     else 
        UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations: 
            sender.transform = sender.transform.rotated(by: -.pi/2)
            sender.isExpanded = false
        , completion: nil)
    
    tableView.beginUpdates()
    tableView.endUpdates()

【问题讨论】:

如果.isExpandedfeedBaseCell 的自定义属性,是否应该是cell.isExpanded 而不是cell.expandButton.isExpanded 您可以选择 UIStackView 来设计您的单元格。单元格将根据可见视图保持其高度。 this ques 的可能重复项。 将您的 expandTheCell 方法添加到您的问题中。 【参考方案1】:

切勿从heightForRowAt 内部呼叫cellForRow(at:)。它会导致无限递归,因为当您请求单元格时,表格视图会尝试获取单元格的高度。

如果你真的,真的需要得到一个单元格来计算它的高度,直接调用你的视图控制器的dataSource方法tableView(_:cellForRowAt:)方法而不是表格视图的cellForRow(at:)方法。

但在这种情况下,您不需要该单元格。您应该将每一行的展开状态存储在数据源数据中,而不是存储在单元格本身中。查看该数据,而不是单元格,以确定 heightForRowAt 方法中的高度。当然,您需要在 cellForRowAt 数据源方法中使用此状态信息,以便您可以在那里设置单元格的状态,因为滚动表格视图时单元格会被重用。

【讨论】:

如何查看数据? 我说的是你的表格视图的数据源使用的数据。 对,如何访问我的表视图数据源中的数据? 你已经是了。您可以在numberOfRowsInSection 方法和cellForRowAt 方法中访问它。 我怎样才能确定heightForRowAt 函数之外的高度呢?我不确定我是否在关注你...

以上是关于EXC_BAD_ACCESS 在 heightForRowAt 内时的主要内容,如果未能解决你的问题,请参考以下文章

为啥在构造函数中释放会导致 EXC_BAD_ACCESS?

释放对象导致 exc_bad_access

为啥我在字符串变量上得到“程序接收信号:”EXC_BAD_ACCESS“

崩溃:“线程 1:EXC_BAD_ACCESS”?

EXC_BAD_ACCESS 在 heightForRowAt 内时

在加载文件时捕获EXC_BAD_ACCESS的方法