【UE4 C++】UObject 创建、销毁、内存管理
UObject 的创建
NewObject 模板类
-
本例使用 UE 4.26,只剩下 NewObject 用来创建 UObject,提供两个带不同可选参数构造函数的模板类
-
Outer 表示这个对象的外部对象,通常可传 this 指针进去
-
Name 为对象名,如果没有自定义,默认生成,自带 GetName() 方法获取
template<class T> T* NewObject(UObject* Outer) { T* Object = ::NewObject<T>(Outer); Object->SetInternalFlags(EInternalObjectFlags::Async); return Object; } template<class T> T* NewObject(UObject* Outer, UClass* Class, FName Name = NAME_None, EObjectFlags Flags = RF_NoFlags, UObject* Template = nullptr, bool bCopyTransientsFromClassDefaults = false, FObjectInstancingGraph* InInstanceGraph = nullptr) { T* Object = ::NewObject<T>(Outer, Class, Name, Flags, Template, bCopyTransientsFromClassDefaults, InInstanceGraph); Object->SetInternalFlags(EInternalObjectFlags::Async); return Object; }
实践
-
创建一个 UObject 类
UCLASS() class TIPS_API UItemObject : public UObject { GENERATED_BODY() FString m_Name; public: UItemObject() { m_Name = GetName(); UE_LOG(LogTemp, Warning, TEXT(__FUNCTION__" %s"), *m_Name); } ~UItemObject() { UE_LOG(LogTemp, Warning, TEXT(__FUNCTION__" %s"), *m_Name); } };
-
创建 UObject 实例
UItemObject* Obj = NewObject<UItemObject>(); UItemObject* Obj2 = NewObject<UItemObject>(this, TEXT("Obj2"));
UObject 的销毁
自动销毁
-
UObject及其派生 具有被 UE4 垃圾回收机制管理,因而当指向对象的指针为 nullptr 后,将会被 UE4 自动回收掉
Obj = NewObject<UItemObject>(this, TEXT("Obj")); Obj = nullptr;
主动销毁
-
UObject::ConditionalBeginDestroy()
- 异步执行且对象在当前帧内持续有效
- 等待下次GC
Obj->ConditionalBeginDestroy(); Obj = nullptr;
-
MarkPendingKill()
- 标记为PendingKill,等待回收。指向此实例的指针将设置为NULL,并在下一次GC时删除。
- IsPendingKill 判断是否处于 PendingKill 状态
- ClearPendingKill 清除 PendingKill 状态
Obj->MarkPendingKill(); Obj = nullptr;
-
Engine\Config \BaseEngine.ini 更改下面参数,设置销毁时间间隔
gc.TimeBetweenPurgingPendingKillObjects=60
强制垃圾回收
-
UWorld::ForceGarbageCollection弃用 -
GEngine->ForceGarbageCollection
GEngine->ForceGarbageCollection(true);
原生对象内存管理
new/delete
-
需要手动清理,易造成内存泄漏
-
delete 一般将指针置为 nullptr ,防止指向的地址不固定
class SimpleObject { public: SimpleObject() { UE_LOG(LogTemp, Warning, TEXT(__FUNCTION__)); } ~SimpleObject() { UE_LOG(LogTemp, Warning, TEXT(__FUNCTION__)); } };
SimpleObject* Obj = new SimpleObject(); delete Obj; Obj = nullptr;
使用智能指针
- 对于非 UObject 的对象,可以使用智能指针进行管理
- 当引用计数为0时,对象自动销毁
UObject 对象内存管理
UPROPERTY() 保持引用
-
支持容器 TArray、TMap 的 <UObject*>类型。TArray、TMap使用UPROPERTY() ,也可以使元素对象常驻内存
UPROPERTY() class UItemObject* m_ItemObject2; UPROPERTY() TArray<class UItemObject*> m_ObjList1;
AddToRoot 和 RemoveFromRoot 标记不被GC/移除标记
-
构造时 和 AddToRoot 一起
-
析构时和 RemveFromRoot 一起
//创建对象 m_ItemObject1 = NewObject<UItemObject>(this,TEXT("m_ItemObject1")); m_ItemObject1->AddToRoot(); // 释放对象 m_ItemObject1->RemoveFromRoot(); m_ItemObject1 = nullptr;
FStreamableManager 资源卸载
-
FStreamableHandle::ReleaseHandle()
TSharedPtr<FStreamableHandle> Handle = UAssetManager::GetStreamableManager().RequestSyncLoad(AssetPath); UObject* Obj = Handle->GetLoadedAsset(); Handle->ReleaseHandle();
AActor 销毁
Destroy()
方法
UActorComponent
DestroyComponent()
方法
扩展:FGCObjectScopeGuard
作者:砥才人
出处:https://www.cnblogs.com/shiroe
本系列文章为笔者整理原创,只发表在博客园上,欢迎分享本文链接,如需转载,请注明出处!