1. 智能指针 TSharedPtr
智能指针TsharedPtr是虚幻自己定义的的指针类型, 用于内存管理,但是继承于UObject的类不需要用智能指针, 用普通的指针就行, 因为继承于UObject的内存回收是靠虚幻自己的GC系统回收的,只有不继承Uobject的类才需要用智能指针,用智能指针去回收。例如Slate等。。。
//声明一个智能指针
Tsharedptr<MyClass> TestPtr;
//给共享指针赋值 效率低 但即使对象构造为 私有的仍可以运行
SharedPtr = MakeShareable(new MyClass());
//创建共享引用 隐式转换为共享指针
SharedPtr = MakeShared<FMyObjectType>();
注意:智能引用可以转换为智能指针, 但是智能指针不能转换为智能引用
2.智能引用 TSharedRef
//共享引用 相对 共享指针 : 不允许被赋值为null 声明时必须初始化 因此共享引用绝对安全
//声明
TSharedRef<MyClass>SharedRef(new MyClass())
//共享引用 可以 隐式转换 为共享指针
SharedPtr = SharedRef
//继承自 TSharedFromThis 的 类 可以通过派生方法直接获取自己的共享引用
SharedRef = MyClass->AsShared();
3. 弱指针TWeakPtr
//声明
TWeakPtr<MyClass> WeakPtr
//赋值
TWeakPtr<MyClass> MyClass_Weak(SharedRef); //通过共享引用创建弱指针
TWeakPtr<MyClass> MyClass_Weak(SharedPtr); //通过共享指针创建弱指针
WeakPtr = SharedRef
WeakPtr = SharedPtr
//获取对象
WeakPtr.Pin() //弱指针随时都有可能是null 使用前需要判空 .Pin获取对象的共享指针
弱指针的计数不会阻止对象被销毁弱指针没办法直接访问对象 必须通过Pin() 来获取共享指针访问对象其共享指针被清空 弱指针也会被清空
4.TSoftobjectPtr和TSoftClassPtr
引用资源
- Hard reference: A引用了B 所以A加载B也会被加载
- Soft reference: A引用了B的路径 A加载只有B的路径(字符串)被加载
4.1 Hard Reference直接资源引用
这个是最常见的引用。
一句话: 在类中暴露一个UPROPERTY变量可以让别人编辑或者指定资源。
构造时引用
即通过ConstructorHelpers在A的构造函数中加载B
ConstructorHelpers先在RAM中查找资源,找不到就加载
UPROPERTY()class B* x;A::A(const FObjectInitializen& ObjectInitializer) : Super(ObjectInitializer){
static ConstructorHelpers::FObjectFinder<B> b(TEXT("path_to_asset"));
x = b.Object;}
4.2 Soft Renference间接资源引用(lazy load)
与直接引用对应,间接引用不存放资源本身而是存放字符串和资源模板(TSoftObjectPtr)。 IsPending()可以检查是否准备好。 用这种方式我们必须手动加载资源(LoadObject, StaticLoadObject, FStreamingManager)。注意同步加载过多可能造成卡顿。
UPROPERTY()TSoftObjectPtr<B> b;B* func(){
if (b.IsPending()) {
const FSoftObjectPath& AssetRef = b.ToStringReference();
b = Cast<B>(Streamble.SynchronousLoad(AssetRef));
}
return b.Get();}
和TSoftObjectPtr对应的还有TSoftClassPtr.
runtime层动态加载
如果资源已经加载完毕: FindObject<>()
如果资源还没加载: LoadObject<>()
A* a = FindObject<A>(Outer, *Name);
b = LoadObject<B>(nullptr, TEXT("asset_path"), nullptr, LOAD_None, nullptr);