870920 Menu

关于ValueTree深度复制的一则教训与实例

近期在做的项目,牵扯到文件、图像,音频、文本等方面的读写、交换与处理。毋容置疑,JUCE类库的ValueTree类实在是得心应手,方便之极。但是经验有时也不靠谱,轻车熟路,漫不经心的丁点草率,都有可能付出巨大的时间代价。

这两天整合调试某模块时,发现一个奇怪的现象:每次跑起来,不管喂进去多少条“记录”(程序中的概念定为note,一个note包含多项数据),明明总文件每次都保存成功了,MVC三者之间运作协调也良好无误,前台显示正常。但是下次启动,只保留了最后的note,其他都不见了。因总文件用了加密技术,懒得写查看单元,就尝试在已有代码中跟一跟。搞了许久无果,郁闷之至。

就在刚刚,迷迷糊糊中象被人敲了一记闷棍,惊觉ValueTree的常规操作全部基于引用,已经加入上级Tree中的子节点,如果做了removeAllProperties(),那么已添加的,此时铁定已无效。同一个子note,哪怕改头换面往父节点中塞N次,其父始终持有的,只不过是最后一个尚未removeAllProperties()的有效数据而已。

这并非故事的全部。此例中,总节点未采用引用策略,独有的ValueTree直接“代表”了磁盘文件,而总节点数据写入磁盘之后,并未真正更新自身。因为刚刚添加的note随后就removeAllProperties()了,该总节点再次往磁盘上写东西,始终只能写入原有数据和本次操作的最后一条。这就导致了该问题的出现。

解决之道:

  1. 每次写文件之后,更新总节点——显然,这个办法太蛮横。
  2. 子节点添加时做个深度复制——OK,就你了。

翻代码,瞬间找到,连呼三声FxxK……

将源码公布于此,以儆效尤。