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

Swift TLV编辑器:增删Item时NSOutlineView父Construction长度同步异常

TLV编辑器删除Item时construction长度不同步问题排查与优化方案

问题排查

1. 目标construction获取逻辑可能出错

删除操作中,你先通过outlineView拿到选中的Item,再调用getConstructionForSelectedItem()反向查找它所属的construction。如果这个方法的实现存在缺陷(比如选中Item时返回了错误的父节点,或者节点层级判断逻辑错误),就会导致从错误的节点开始扣减长度,最终出现同步异常。
对比添加逻辑:添加时是先明确目标construction再执行添加,节点指向清晰;但删除时的反向查找更容易出现偏差。

2. 删除与长度更新的顺序错误

当前删除逻辑是先修改construction.clength -= ctr,再调用viewModel.remove(item: selectedItem, from: construction)。如果viewModel.remove内部存在隐含的长度修改逻辑(比如误操作重复扣减),或者删除操作失败(比如Item不在目标construction的列表中),都会导致长度数据不一致。正确的顺序应该是先执行删除操作,确认成功后再更新长度。

3. 父节点链的完整性问题

遍历父节点更新长度时,依赖construction.parent的正确性。如果在添加construction到上级节点时,没有正确设置parent属性,或者Item归属关系变更时parent链没有同步更新,就会导致上级节点的长度无法被正确修改。

更优解决方案:用计算属性替代手动维护长度

与其每次增删操作都手动遍历更新所有父节点的长度,不如将clength改为计算属性,让它自动根据子项的长度求和,从根源上避免同步问题。

修改Construction类的核心代码:

class Construction: Equatable {
    var id: Int?
    // 替换为计算属性,自动计算总长度
    var clength: Int {
        var totalLength = 0
        for item in items {
            if let normalItem = item as? Item {
                totalLength += normalItem.length
            } else if let subConstruction = item as? Construction {
                totalLength += subConstruction.clength
            }
        }
        return totalLength
    }
    var parent: Construction?
    var items = [Any]()
    // ... 其他原有代码
}

方案优势

  • 彻底消除手动维护长度的繁琐逻辑,增删Item、子construction长度变化时,clength会自动实时计算,从根源解决同步问题。
  • 层级嵌套再多也能保证长度正确,父节点的clength会自动依赖子节点的计算结果。
  • 减少代码冗余,降低出错概率。

额外优化建议:在Item类中添加parentConstruction: Construction?属性,当Item被添加到某个construction时直接设置该属性,删除时可直接通过selectedItem.parentConstruction获取所属节点,避免通过outlineView反向查找的潜在错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 23:27:10