UObject gc机制
1)TArray保持引用如果有个TArray容器,则这个TArray需要用一个UPROPERTY()去保持容器的引用,然后里面的UObject就不需要再去AddToRoot去阻止被gc了。
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "UCoolDownComponent")
TArray<UCoolDown*> mCDArr;
UCoolDown* cd = NewObject<UCoolDown>(_class);
cd->SetSkillId(_skillId);
mCDArr.Add(cd);
容器clear后,元素会自动被gc
2)TMap不能保持引用所以为安全起见,任何时候,不管是TArray还是TMap,元素都AddToRoot一下,需要删除的时候就RemoveFromRoot
3)没有任何容器保持引用需要AddToRoot添加标记去阻止被gc
m_sInstance = NewObject<T>();
m_sInstance->AddToRoot();
同时需要移除标记
m_sInstance->RemoveFromRoot();
m_sInstance = nullptr;
UActorComponent gc机制
1)依附于一个宿主Actor,销毁Actor则UActorComponent坐等被gc一般一个组件都是依附在一个actor中,所以创建需要添加一个宿主Outer的引用,然后注册一下,当宿主销毁的时候,组件的宿主引用就无效了,会在一个不定时的时间被gc掉
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MyChar")
UCoolDownComponent* mCDComp;
mCDComp = NewObject<UCoolDownComponent>(this, TEXT("CDComponent"));
mCDComp->RegisterComponent();
2)任意时刻销毁,即使宿主Actor未被销毁C++销毁则直接调用接口
void UActorComponent::DestroyComponent(bool bPromoteChildren/*= false*/)
蓝图销毁,需要设置一个UActorComponent的属性
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
{
UE_LOG(LogActorComponent, Error, TEXT("May not destroy component %s owned by %s."), *GetFullName(), *MyOwner->GetFullName());
}
}
3)一般重写这两个函数,替代构造和析构函数
virtual void BeginPlay() override;
virtual void BeginDestroy() override;
默认的gc是时间测试得到为1min