UE4-为什么要收集UObject的TArray?

时间:2019-02-15 15:46:42

标签: unreal-engine4

我的垃圾收集器有一些问题,但是我不明白为什么?

我在GameInstance中创建了一个名为“ WorldModel”的UObject,并将其存储(带有UPROPERTY的指针)。

在此“ WorldModel” UObject中,我具有一个带有“ UPROPERTY”宏的名为“ WorldPlayerModel”(TArray)的UObject数组。

当我加载新地图时,我的“ WorldModel”仍然在这里,“ WorldPlayerModel”的数组也是如此,但是其中的所有UObject都被垃圾收集器破坏并为空。

根据文档,我的UObject不应该被销毁,所以我不明白为什么?

感谢您的帮助。

3 个答案:

答案 0 :(得分:2)

谢谢您的链接。我不太明白为什么它可以使用自定义名称,但是我发现了我的真正问题:数组中的UObject是使用外部容器创建的,该外部容器在新地图加载过程中被破坏了。 >

答案 1 :(得分:2)

通常,当您创建子对象属性并将其标记为反映的UPROPERTY时,引擎会自动将子对象添加到根集中,以防止意外的GC收集。

但是,当您创建UObject,AActor或AActorComponent派生的类型并将它们存储在TArray属性中而不是作为某个东西的“实际”子对象时,它们不会自动添加到根集中,您必须执行所以你自己,否则它们将被意外地GC(通常也很快!)。

要手动执行此操作,只需在创建每个UObject之后将其添加到TArray中,然后在每个UObject上调用 AddToRoot()。这将确保在对父对象进行GC或您为引用的UObject手动调用 RemoveFromRoot()之前强制对每个对象进行引用。

此外,如果您恰好将AActorComponent派生的类型存储在TArray中,则还需要向引擎手动注册该组件,否则将不会更新。创建后,可以通过在组件上调用 RegisterComponent()来轻松完成此操作。

AddToRoot documentation

RemoveFromRoot documentation

RegisterComponent documentation

答案 2 :(得分:0)

奇怪...很久以前已经有人问同样的问题:https://answers.unrealengine.com/questions/410789/tarray-of-uobjects-getting-garbage-collected.html; 尝试命名您的对象(至少可以尝试使用他的解决方案,即使这只是一种解决方法)