You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

UE4.27使用TSharedPtr销毁持有的蓝图生成Actor时触发断言异常问题

问题根因

你触发断言的核心原因是:UE的UObject(包括所有AActor子类)的生命周期由引擎自带的垃圾回收(GC)系统统一管理,完全不支持用TSharedPtr这类原生C++智能指针持有。
TSharedPtr的引用计数逻辑和UE GC体系完全独立,你调用SharedPointerObjectPtr.Reset()时,TSharedPtr会直接delete所持有的Actor内存,完全绕过了UE销毁UObject的标准流程:UE要求销毁UObject前必须先清理引擎侧绑定的名称、标记、生命周期状态,其中就包括将对象名重置为NAME_None,直接delete没有执行这步逻辑,自然就触发了GetFName() == NAME_None的断言。


修复方案

UE针对UObject类型提供了专门的指针方案,不要用TSharedPtr持有UObject对象:

  1. 如果你需要持有强引用、阻止GC回收对象,直接用被UPROPERTY()标记的裸指针即可,UE GC会自动扫描标记了该宏的指针,只要指针不为空就不会回收所持对象。
  2. 如果你只需要弱引用、不想影响GC回收逻辑,使用UE专门为UObject设计的弱指针TWeakObjectPtr即可。

代码修改示例

1. 指针定义修改(APointersManager.h)
// 强引用方案:加UPROPERTY标记
UPROPERTY()
APointerReferencedActor* SharedPointerObjectPtr = nullptr;

// 弱引用方案:用TWeakObjectPtr,不需要加UPROPERTY
// TWeakObjectPtr<APointerReferencedActor> SharedPointerObjectPtr;
2. 赋值逻辑不变
SharedPointerObjectPtr = Cast<APointerReferencedActor>(GetWorld()->SpawnActor(SharedPointerClass));
3. 释放&销毁逻辑修改

不要靠智能指针的Reset销毁对象,主动调用Actor的Destroy()方法走引擎标准销毁流程:

// 先判断对象是否有效
if (IsValid(SharedPointerObjectPtr))
{
    // 走引擎标准销毁流程
    SharedPointerObjectPtr->Destroy();
    // 清空指针引用,方便GC回收
    SharedPointerObjectPtr = nullptr;
}

额外注意

TSharedPtr、TUniquePtr这类UE提供的通用智能指针,仅用于持有非UObject派生的原生C++对象,不要和UObject体系混用,否则要么触发断言崩溃,要么出现野指针访问问题。

内容的提问来源于stack exchange,提问作者Bisher Dokkmak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 16:54:04