原文链接:https://blog.csdn.net/yangxuan0261/article/details/52075581
1.UObject GC机制
1.1 GC方式
推荐阅读:
https://blog.csdn.net/qq826364410/article/details/97691497
https://www.cnblogs.com/ghl_carmack/p/6112118.html
1.2 如何防止对象被自动GC
1.标记UPROPERTY()可以保持引用
2.储存在TArray、TMap容器中,通过容器保持对对象的引用,但容器必须被UPROPERTY()保持引用,当容器clear时,元素会自动被GC
3.通过AddToRoot添加标记阻止被GC;通常和RemoveFromRoot配合使用,RemoveFromRoot时并不是立即释放对象,而是标记了这个对象可以被GC,等到GC的时候才真正释放
4.定义在C++中的方法如果创建了一个UObject对象,在蓝图中调用这个C++方法后,需要在蓝图中第一时间用一个变量去引用住,就可以防止这个对象被GC掉。当这个变量不再引用这个对象时,这个对象则认为可被GC
1.3 强制GC
GWorld->GetWorld()->ForceGarbageCollection(true);
2.AActor GC机制
2.1 Actor的创建和销毁
调用SpawnActor或DestroyActor来创建和销毁Actor。
DestroyActor表示从当前世界中删除Actor,但GC时对象才真正释放,析构函数要在GC时才调用。
2.2 一般重写这些方法,来做一些初始化和清理工作
virtual void PostActorCreated() override; //做初始化工作
virtual void BeginPlay() override; //做初始化工作
virtual void BeginDestroy() override; //引擎在gc的时候调用,并不是立即调用,一般不用
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override; //做清理工作
virtual void Destroyed() override; //用于释放成员,调用Destroy();会立即调用
3.UActorComponent GC机制
3.1 创建ActorComponent
myActorComponent = NewObject<MyActorComponent >(this, TEXT("MyActorComponent "));
//注册组件
mCDComp->RegisterComponent();
或者
CreateDefaultSubobject<>();
3.2 销毁ActorComponent
1.销毁持有的Actor时
作为Actor的组件存在于Actor的组件列表中,销毁Actor的时候会把组件列表遍历一遍Destroy掉并标记为可GC的对象,在一个不定时的时间被GC掉
2.在任意时刻销毁,即使持有的Actor还没被销毁
1)c++销毁直接调用接口DestroyComponent
void UActorComponent::DestroyComponent(bool bPromoteChildren/*= false*/)
2)蓝图销毁,需要设置一个UActorComponent的属性bAllowAnyoneToDestroyMe
bAllowAnyoneToDestroyMe = true;
在提供给蓝图的接口需要判断这个字段,默认是false
UFUNCTION(BlueprintCallable, Category="Components", meta=(Keywords = "Delete", HidePin="Object", DefaultToSelf="Object", DisplayName = "DestroyComponent"))
void K2_DestroyComponent(UObject* Object);
void UActorComponent::K2_DestroyComponent(UObject* Object)
{
AActor* MyOwner = GetOwner();
if (bAllowAnyoneToDestroyMe || Object == this || MyOwner == NULL || MyOwner == Object)
{
DestroyComponent();
}
else
{
// TODO: Put in Message Log
UE_LOG(LogActorComponent, Error, TEXT("May not destroy component %s owned by %s."), *GetFullName(), *MyOwner->GetFullName());
}
}
3.3 一般重写这些方法,做一些初始化和清理工作
// Begin UActorComponent Interface.
virtual void BeginPlay() override; //组件RegisterComponent注册的时候,且有OwnerActor才会立即调用,一般不用
virtual void BeginDestroy() override; //引擎在gc的时候调用,并不是立即调用,一般不用
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override; //立即调用,一般这里做清理工作(注册过才会调用),且gc时还会再调用一次,一般不用
virtual void OnComponentCreated() override; //组件RegisterComponent注册的时候立即调用,一般这里做初始化工作
virtual void OnComponentDestroyed(bool bDestroyingHierarchy) override;//立即调用,一般这里做清理工作(只要DestroyComponent就会调用)
// End UActorComponent Interface.