(UE4 4.20 )UE4的GC(垃圾回收)程式設計規範
GC標記
UPROPERTY 引用
當我們在一個UObject類宣告各種繼承UObject的 變數時,得加UPROPERTY(), 這個可以讓UE4幫我們自動管理UObject的垃圾回收。UPROPERTY不僅僅用於反射變數到編輯器上編輯,也涉及UObject變數的GC。
如下面所示:
UCLASS(config=Game)
class AMyProject1Character : public ACharacter
{
GENERATED_BODY()
private:
UPROPERTY()
UObject* object;
}
TWeakObjectPtr
UE4裡自創一套C++ GC規則,官方並不推薦使用C++標準庫。 學C++的同學可能會對弱指標熟悉,可以訪問一個物件又不造成引用計數加1。通常定義在一個類內,用於獲取其他物件的某個變數當成臨時變數方便訪問。如下面所示:
UCLASS()
class MYPROJECT3_API ATestActor : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
ATestActor();
UPROPERTY(VisibleAnywhere)
class UCameraComponent* cameraComponent;
};
ATestActor::ATestActor()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
cameraComponent = CreateDefaultSubobject<UCameraComponent>(TEXT("Camera"));
cameraComponent->SetupAttachment(RootComponent);
}
UCLASS(config=Game)
class AMyProject3Character : public ACharacter
{
GENERATED_BODY()
public:
TWeakObjectPtr<UCameraComponent> cameraComponent;
protected:
virtual void BeginPlay() override;
}
void AMyProject3Character::BeginPlay()
{
Super::BeginPlay();
TArray<AActor*> arrayActor;
UGameplayStatics::GetAllActorsOfClass(GetWorld(), ATestActor::StaticClass(), arrayActor);
if (arrayActor.Num() > 0)
{
ATestActor* testActor = Cast<ATestActor>(arrayActor[0]);
if (nullptr == testActor)
return;
cameraComponent = testActor->cameraComponent;
}
}
這裡CameraComponent元件建立與Te'stActor,但是AMyproject2Character需要儲存臨時變數的時候就用弱指標儲存。
區域性建立的UObject物件GC
區域性建立並且在區域性使用的UObject要呼叫AddToRoot來防止被GC, 然後 RemoveFromRoot來移除引用能得到GC
UCLASS()
class MYPROJECT4_API UTestObject : public UObject
{
GENERATED_BODY()
public:
UTestObject()
{
}
float a;
};
void AMyProject4Character::BeginPlay()
{
Super::BeginPlay();
UTestObject* testObject = NewObject<UTestObject>(this);
testObject->AddToRoot();
testObject->a = 1.0f;
UE_LOG(LogTemp, Error, TEXT("xxxx = %f"), testObject->a);
testObject->RemoveFromRoot();
}
TSharedPtr
共享智慧指標,類似C++標準庫的共享智慧指標,不能用於UObject物件(TWeakPtr倒是可以用於UObject), 因為UObject有自己 專門GC的一套規則。總之TSharedPtr用於自定義的結構體(不繼承UObject)。
如下所示:
class MYPROJECT2_API FTest
{
public:
FTest();
~FTest();
};
#include "FTest.h"
FTest::FTest()
{
UE_LOG(LogTemp, Warning, TEXT("1111FTest Constrction"));
}
FTest::~FTest()
{
UE_LOG(LogTemp, Warning, TEXT("2222FTest Deconstrction"));
}
UCLASS()
class MYPROJECT2_API ATestActor : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
ATestActor();
TSharedPtr<FTest> Test;
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
}
// Called when the game starts or when spawned
void ATestActor::BeginPlay()
{
Super::BeginPlay();
Test = MakeShareable(new FTest());
}
PIE執行時Actor建立:
PIE取消執行Actor銷燬:
如果是區域性變數的結構體建立TSharedPtr:
void ATestActor::BeginPlay()
{
Super::BeginPlay();
TSharedPtr<FTest> Test;
Test = MakeShareable(new FTest());
}
FGCObject
上面我們說到了UObject的情況,採用NewObject建立和UPROPERTY()標記來進行GC。而不繼承UObject的自定義結構體採用MakeShareable來建立,用TSharedPtr來管理GC。這時候一個特殊的情況出現了玩意,一個不繼承UObject的結構體中出現UObject物件怎麼辦?如下面所示:
*/
UCLASS(BlueprintType, notplaceable, MinimalAPI)
class UCameraAnim : public UObject
{
。。。。。。。。。。。。。。。。。。。。。。。。
}
class UCameraAnim;
/**
*
*/
class MYPROJECT2_API FTest
{
public:
FTest();
~FTest();
UPROPERTY()
UCameraAnim* CameraAnim;
};
這種情況下,我試過,如果用MakeShareable建立結構體指標,然後直接操作結構體的UObject物件進行NewObjec建立,結構體本身的訪問沒問題,但是結構體裡面的UObject物件一段時間後自動GC掉,成為野指標,不能訪問。這種情況怎麼解決呢?UE4為我們提供了FGCObject ,我們的結構體繼承FGCObject ,然後用AddReferencedObjects 方法引用結構體裡的所有UObject物件,這裡的UObject物件不需要被UPROPERTY()標記, 如下所示
#include "GCObject.h"
class UCameraAnim;
/**
*
*/
class MYPROJECT2_API FTest :public FGCObject
{
public:
FTest();
~FTest();
UCameraAnim* CameraAnim;
protected:
virtual void AddReferencedObjects(FReferenceCollector& Collector) override
{
Collector.AddReferencedObject(CameraAnim);
}
};
TSharedRef
相關文章
- (UE4 4.20)UE4 TimeLine(UTimelineComponent)
- (UE4 4.20)UE4 UCLASS,UENUM, USTRUCT, UPROPERTY 的 常用配置Struct
- Unity GC垃圾回收UnityGC
- GC垃圾回收器GC
- UE4中C++程式設計(一)C++程式設計
- (UE4 4.20)UE4 如何判斷一個點是否在導航網格(Navigation)內Navigation
- .Net平臺的GC垃圾回收GC
- 十種GC垃圾回收器GC
- 聊聊JVM的垃圾回收機制GCJVMGC
- (UE4 4.20)UE4 繼承AnimNotify建立自定義動畫通知事件(結合PoseableMeshComponent實現技能殘影效果)繼承動畫事件
- 託管堆和垃圾回收(GC)GC
- 秋招乾貨 - JVM 垃圾回收(GC)JVMGC
- GC 分代回收 - 垃圾收集器GC
- [Inside HotSpot] Serial垃圾回收器Full GCIDEHotSpotGC
- JS程式設計規範JS程式設計
- React程式設計規範React程式設計
- python程式設計規範Python程式設計
- 程式設計小記-程式設計規範程式設計
- JVM學習(二)——GC垃圾回收機制JVMGC
- [Inside HotSpot] Serial垃圾回收器 (二) Minor GCIDEHotSpotGC
- JDK 18 GC垃圾回收機制比較JDKGC
- 【JVM第八篇--垃圾回收】GC和GC演算法JVMGC演算法
- JVM垃圾回收——新生代,老年代,永久代,Minor GC,Full GCJVMGC
- java學習筆記-4 JVM垃圾回收(GC)Java筆記JVMGC
- UE4委託
- UE4的移動碰撞
- Java虛擬機器-GC垃圾回收演算法-引用計數法Java虛擬機GC演算法
- Go 語言程式設計規範Go程式設計
- python 程式設計規範有哪些?Python程式設計
- 程式設計命名規範(網文)程式設計
- 【Android面試-Java-V05】Java GC 垃圾回收Android面試JavaGC
- 為什麼GC(垃圾回收)必須stop-the-world?GC
- 併發程式設計的12條規範程式設計
- 深入理解Java的垃圾回收機制(GC)實現原理JavaGC
- 《Inside UE4》開篇IDE
- UE4 智慧指標指標
- 垃圾回收(一)【垃圾回收的基礎】
- 垃圾回收演算法|GC標記-清除演算法演算法GC