【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;
    

    image

使用智能指針

  • 對於非 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;
    

    image

FStreamableManager 資源卸載

  • FStreamableHandle::ReleaseHandle()

    TSharedPtr<FStreamableHandle> Handle  = UAssetManager::GetStreamableManager().RequestSyncLoad(AssetPath);
    UObject* Obj = Handle->GetLoadedAsset();
    Handle->ReleaseHandle();
    

AActor 銷毀

  • Destroy() 方法

UActorComponent

  • DestroyComponent() 方法

擴展:FGCObjectScopeGuard


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM