1.非UObject物件
即非UObject常規C++物件,創建銷毀不贅述,但可以用智能指標;從而不用關心銷毀邏輯:
TSharedPtr<ClassA> MyObj = MakeShareable(new ClassA());
智能指標轉裸指標:
ClassA* MyObjPtr = MyObj.Get();
智能指標情況下,當別的類參考該物件,并要知道參考的欄位是否=nullptr,則需使用弱指標(TWeakPtr):
class ClassB { public: TWeakPtr<ClassA> ClassAReference; };
ClassB ClassBObj; ClassBObj.ClassAReference = MyObj; //... if (ClassBObj.ClassAReference.IsValid()) { //... }
2.場景參考的UObject物件
第二種是鏈接在場景中的UObject物件,UObject本身不會產生釋放銷毀問題,因為走的是UE自己的垃圾回收,
但有時會無法獲取當前物件是否已銷毀的狀態,
例如:
UCLASS() class AMyClass : public ACharacter { GENERATED_BODY() public: class UActorComponent* TestUObj; //...
TestUObj沒有加UPROPERTY,此時無法判斷是否銷毀:
TestUObj->DestroyComponent();//銷毀測驗1 TestUObj->MarkPendingKill();//銷毀測驗2,都沒用 if (TestUObj) UE_LOG(LogTemp, Log, TEXT("Not Destroy!"));//最后一定進到這里 else UE_LOG(LogTemp, Log, TEXT("Destroyed!"));
還有個介面IsPendingKillOrUnreachable,不過只是PendingKill的期間可以得到正常的值,銷毀后仍不對,
回到剛剛的AMyClass,加上UPROPERTY宏,即可解決,UE會跟蹤其生命周期:
UPROPERTY(VisibleAnywhere)//加上 class UActorComponent* TestUObj;
但如果不想用UPROPERTY又需要知道當前物件是否已銷毀,則可以用弱物件指標
(TWeakObjectPtr和TWeakPtr弱指標的區別是,TWeakObjectPtr針對UObject型別,TWeakPtr針對常規C++物件):
TWeakObjectPtr<UActorComponent> ptr = MakeWeakObjectPtr(TestUObj);//弱物件指標 TestUObj->DestroyComponent();//銷毀 if (ptr.IsValid()) { UE_LOG(LogTemp, Log, TEXT("Not Destroy!")); } else { UE_LOG(LogTemp, Log, TEXT("Destroyed!"));//正常了 }
3.動態創建的UObject物件
動態創建的物件主要問題是,每隔一段時間物件就會自動被垃圾回識訓制銷毀,隨后UE崩潰,彈窗報錯Pure Virtual Function...
而此時只需要呼叫一下AddToRoot即可避免被回收:
TestUObj = NewObject<UActorComponent>(this, TEXT("Dynamic Obj1")); TestUObj->AddToRoot();//這真是個坑
在釋放時,需要手動呼叫RemoveFromRoot,否則UE會斷言報錯:
TestUObj->RemoveFromRoot();
4.UInterface介面物件的釋放
UInterface是UE使用的介面型別,可以支持是否實作判斷,介面繼承等,但使用UE介面的物件必須繼承自UObject類,
雖然繼承UObject說明是自動管理釋放的,但如果需要手動控制釋放,則可拿到_getUObject進行處理,
特別是要做RemoveFromRoot呼叫的動態創建物件:
IMyInterface* myInterface; myInterface->_getUObject()->RemoveFromRoot();
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/472288.html
標籤:其他
