做图的ppt模板下载网站,中国前十强企业,网页制作培训学费,做网站包括备案吗UE4的垃圾回收 1 UObjects及子类1.1 UObjects类包含UObjects成员#xff08;UPROPERTY#xff09;1.2 UObjects类包含非UObjects成员 2 非UObject及子类2.1 非UObjects类包含UObjects成员12.2 非UObjects类包含UObjects成员22.3 非UOjbects类包含非UObjects成员 3 UStructs4 … UE4的垃圾回收 1 UObjects及子类1.1 UObjects类包含UObjects成员UPROPERTY1.2 UObjects类包含非UObjects成员 2 非UObject及子类2.1 非UObjects类包含UObjects成员12.2 非UObjects类包含UObjects成员22.3 非UOjbects类包含非UObjects成员 3 UStructs4 容器类TArray、TMap、TSet4.1.当容器类存储了任意 UObjects指针4.2.当容器类存储了UObjects类外的指针4.3.UE4帮助文档摘抄 1 UObjects及子类
虚幻4引擎使用反射系统机制去实现垃圾回收。关于垃圾回收你不用进行手动的去销毁你的UObjects类对象你只需要保持对他们的引用。你的类需要继承UObject 类以支持垃圾回收。下面有个简单的例子。
UCLASS()
class MyGCType : public UObject
{GENERATED_BODY()
};在垃圾回收器里这里有个概念被称为 root set 根集。根集是一个基本的对象列表回收器不会回收根集的对象。一个对象的引用路径如果在根集里那么它将不会被回收。如果一个对象不存在这种引用路径称之为“unreachable”(无法访问)并且在下次垃圾回收器运行时被回收销毁。引擎将在一定时间间隔运行垃圾回收。
1.1 UObjects类包含UObjects成员UPROPERTY
本节以AActors继承自UObjects的一个继承类AMyActor为例说明。 Actor通常不被垃圾回收。当你在关卡中生成Actor后如果需要在关卡卸载前销毁Actor你需要手动的调用Destroy() 方法去销毁但它们不会被立刻的销毁而是在下一个垃圾回收时期被销毁。 下面是一个常见的情况你的Actor有UObject 类型的属性。
UCLASS()
class AMyActor : public AActor
{GENERATED_BODY()public:UPROPERTY()MyGCType* SafeObject;MyGCType* DoomedObject;AMyActor(const FObjectInitializer ObjectInitializer): Super(ObjectInitializer){SafeObject NewObjectMyGCType();DoomedObject NewObjectMyGCType();}
};void SpawnMyActor(UWorld* World, FVector Location, FRotator Rotation)
{World-SpawnActorAMyActor(Location, Rotation);
}当我们调用上面的函数时我们在世界中生成一个Actor。Actor的构造函数创建2个对象。一个被标记了UPROPERTY另一个使用普通的指针。由于Actor本来就是根集的一部分SafeObject 将不会被垃圾回收因为它在根集中可以被访问。然而DoomedObject将不会那么幸运我们没有对它标记UPROPERTY所以回收器将不知道它的引用所以事实上它会被销毁。 当一个UObject 被垃圾回收所有的UPROPERTY 类型的引用都将变成空指针。你最好在使用时检查一下是否存在空指针。
if (MyActor-SafeObject ! nullptr)
{// Use SafeObject
}正如我前面提到的这非常的重要Actor如果已经执行了Destroy() 方法它将不会被移除直到下次垃圾回收。你可以使用IsPendingKill() 方法去检查这个UObject是否在被等待销毁。如果方法返回Ture意味着这个UObject 已经无用了。 总结1UObjects对象本身已经加入回收机制2成员为UObjects对象时需要UPROPERTY()以加入回收机制否则不能加入回收机制。
1.2 UObjects类包含非UObjects成员
总结1UObjects对象本身已经加入回收机制2成员不为UObjects对象时比如基本数据类型int、float指针、结构体指针等自行new/delete。
2 非UObject及子类
2.1 非UObjects类包含UObjects成员1
通常非UObjects对象它能够添加一个对象引用而避免被垃圾回收。为了达到这种效果你的类必须继承FGCObject 并且重写AddReferencedObjects 。
class FMyNormalClass : public FGCObject
{
public:UObject* SafeObject;FMyNormalClass(UObject* Object): SafeObject(Object){}void AddReferencedObjects(FReferenceCollector Collector) override{Collector.AddReferencedObject(SafeObject);}
};我们使用FReferenceCollector 为我们所需要的UObject 对象手动添加一个硬引用使其不能被垃圾回收。当这个对象FMyNormalClass被销毁并且析构函数执行该对象将会自动清除它所添加的引用。 总结1非UObjects对象借助UObjects成员且继承FGCObject同时重写AddReferencedObjects使得非UObjects对象与UObjects成员都加入回收机制。
2.2 非UObjects类包含UObjects成员2
如果在非UObjects类中有一个UObject* A变量那么在创建完该变量之后最好在非UObjects类的构造函数中使用AddToRoot这样该变量就不会被UE4自动GC。
UObject* A NewObject();
A-AddToRoot();然后在非UObjects类的析构函数中使用RemoveFromRoot即可自动让UE4GC防止内存泄漏。
A-RemoveFromRoot();总结1非UObjects对象包含的UObjects成员通过AddToRoot和RemoveFromRoot使得UObjects成员都加入回收机制2非UObjects对象自行new/delete。
2.3 非UOjbects类包含非UObjects成员
总结自行new/delete。
3 UStructs
UE4中提到 “UStructs正如前面提到可以理解为轻量级的UObject。比如说UStructs 不会被垃圾回收。如果你必须要用UStructs 类型的动态实例你可能需要使用智能指针去代替我们后面会提到。” 自己认为 同“2 非UObject及子类”的说明。
4 容器类TArray、TMap、TSet
容器类一般作为类成员存在以下按照其存储内容介绍。
4.1.当容器类存储了任意 UObjects指针
当容器类存储了任意 UObjects指针也可被视为将UObjects对象加入垃圾回收机制但是需要在以下两种情况中1当容器类作为UObjects类的成员时需要加UPROPERTY2当容器类作为非UObjects类的成员时需要非UObjects类继承FGCObject并重写FGCObject::AddReferencedObjects()函数与“2.1 非UObjects类包含UObjects成员1”不同的是需要在FGCObject::AddReferencedObjects()内调用FReferenceCollector::AddReferencedObjects()函数有多个对容器类的重载版本。
4.2.当容器类存储了UObjects类外的指针
请自行new/delete。
4.3.UE4帮助文档摘抄
摘抄1 UPROPERTY 或UE4容器类例如TArray中存储的任意 UObject 指针都被视为垃圾回收的引用。首先让我们从简单示例入手。摘抄2 TArray 添加了对其元素进行垃圾回收的好处。这样会假设 TArray 存储了 UObject 派生的指针。
UCLASS()
class UMyClass : UObject
{GENERATED_BODY();// ...UPROPERTY()AActor* GarbageCollectedActor;UPROPERTY()TArrayAActor* GarbageCollectedArray;TArrayAActor* AnotherGarbageCollectedArray; //从这看不加UPROPERTY也行
};