ScriptableObject深拷贝

深拷贝ScriptableObject可以使用Object.Instantiate

1
2
3
4
5
6
7
public static StandardClip CopyClip(AETimelineAsset asset, int trackIndex, int clipIndex)  
{
StandardClip clip, newClip;
var tempAsset = Object.Instantiate(asset);
newClip = tempAsset.Tracks[trackIndex].Clips[clipIndex];
return newClip;
}

但是不知道这样会不会造成内存泄漏?

答案是会,在这种情况下,如果父对象的引用没有被持有,但是它的成员对象的引用被持有了,会导致父对象无法被垃圾回收,从而可能造成内存泄漏。示例中,即使 tempAsset 是一个临时变量,在函数返回后会被销毁,但是 newClip 对象仍然保留了对 tempAsset 的引用,因为它是从 tempAsset 中获取的。

要解决这个问题,可以在提取 newClip 对象时将其完全分离。

比如将newClip深拷贝。

方案一

StandardClip并不是继承自Object的对象不能使用Object.Instantiate(StandardClip)

那我们可以将他定义为ScriptableObject。

可行性分析

可行,因为使用工厂模式,所有的clip track,的创建都是在工厂中进行,修改起来方便

后期如果使用ScriptableObject嵌套有问题修改起来也方便

引出问题

无法展开Clip,意味着无法修改数据后即时保存

但是如果能够找到他的父亲ScriptableObject也不是无法解决。

暂时先放弃即时保存。

引出问题

在整个资产中Clip加载为,类型丢失,并且在再次打开项目后资源丢失

解决方案,使用嵌套的ScriptableObject

1
2
AssetDatabase.AddObjectToAsset(clip, asset);  
Save(asset, path);

删除时,要对应的

1
2
3
AssetDatabase.RemoveObjectFromAsset(asset.Tracks[trackIndex].Clips[clipIndex]);  
asset.Tracks[trackIndex].Clips.RemoveAt(clipIndex);
Save(asset, path);

欸,这下恰好可以解决即时保存的问题了,只要保存子Clip就可以了。

方案二

自定义深拷贝函数。

不好实现。

可以使用反射。

可以使用反射。