You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

移除NSTableView列时如何让绑定的CMYK对象自动执行deinit

解决移除NSTableView列时绑定对象未释放的问题

我来帮你梳理下这个问题的核心原因,以及对应的解决办法:

问题根源

你已经从colors数组里移除了CMYK对象,也删除了对应的表格列,但对象的deinit没触发,说明还有其他地方持有该对象的强引用。这里最可能的是:NSTableView的列(或者它内部的cell/缓存)还保留着对CMYK对象的强引用,哪怕你移除了列,这个引用没被及时切断,ARC就无法释放对象。

解决方案

我们需要在移除列之前,主动切断表格列和对象之间的强引用,具体修改你的removeTableColumn方法即可:

@IBAction func removeTableColumn(_ sender: Any) {
    guard let column = tableView.tableColumns.last, 
          let idx = tableView.tableColumns.firstIndex(of: column) else {
        return
    }
    // 关键步骤:先清空该列对应行的objectValue,切断表格对对象的强引用
    tableView.setObjectValue(nil, for: column, row: 0)
    // 再从数据源数组移除对象
    colors.remove(at: idx)
    // 移除表格列
    tableView.removeTableColumn(column)
    tableView.reloadData()
}

额外优化建议

你的数据源实现用硬编码的identifier判断索引,扩展性很差,建议改成动态匹配索引的方式,后续增减列都不用修改这部分代码:

extension ViewController: NSTableViewDataSource {
    func numberOfRows(in tableView: NSTableView) -> Int {
        return 1
    }
    
    func tableView(_ tableView: NSTableView, objectValueFor tableColumn: NSTableColumn?, row: Int) -> Any? {
        guard let colIdStr = tableColumn?.identifier.rawValue,
              let colIndex = Int(colIdStr),
              colIndex < colors.count else {
            return nil
        }
        return colors[colIndex]
    }
}

原理说明

当你调用tableView.setObjectValue(nil, for: column, row: 0)时,会让NSTableView主动释放对该列对应行对象的强引用。此时colors数组也移除了对象,没有其他强引用存在,ARC就会自动调用CMYK对象的deinit方法,你就能在控制台看到对应的打印信息了。

如果之后还是没触发deinit,可以检查下是否有其他地方(比如闭包、全局变量、其他视图组件)持有了CMYK对象的强引用,逐步排查即可。

内容的提问来源于stack exchange,提问作者CocoaUser

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 17:58:12