内容纲要
在使用多线程之前,了解委托是必要条件,因为在跨线程调用时会用到它
- 不适用委托的调用
Object *obj = new Object;
obj -> Function();
- 使用委托调用
Delegate del;
del.bind(obj, Object::Function);
del.Execute();
总结:不使用委托就是获取到对象的实例,直接进行调用;委托是将方法注册到委托列表中再调用,在调用时不关心实例化的对象是谁~
目录
委托的声明
支持返回值的函数、声明为"const"的函数、最多4个"负载"变量、最多8个函数参数。新版的好像支持9个,这个会随UE4的更新而变化~
负载是绑定委托的时候传参,普通传参是调用时候传的。
- 无返回值,无参数的声明
DECLARE_DELEGATE(FTestDelegate)
- 有返回值,无参数的声明
DECLARE_DELEGATE_RetVal(bool, FTestDelegate_Ret);
- 无返回值,有参数的声明
DECLARE_DELEGATE_OneParam(FTestDelegate_Bool, bool);
声明的位置和 C# 类似,类里面是内部的,类外面是公共的。
绑定委托
FTestDelegate& UDelegateMaker::MakeDelegate(EDelegateType Type)
{
if(Delegate.IsBound())
{
Delegate.Unbind();
}
Switch(Type)
{
case EDelegateType::Object: //绑定UE4对象,就是继承UE4类的对象
if(UEObject == nullptr)
{
UEObject = NewObject<UDelegateObject>();
}
Delegate.BindUObject(UEObject, &UDelegateObject::TestDelegate);
break;
case EDelegateType::Lambda:
Delegate.BindLambda(
[](void){
UE_LOG(LogTemp, Warning, TEXT(_FUNCTION_);
}
);
break;
case EDelegateType::Raw: //绑定原始指针,就是不继承UE4的对象
if(!RawObjectPtr.IsValid())
{
RawObjectPtr = MakeShareable(new RawObject);
}
Delegate.BindRaw(RawObjectPtr.Get(), &RawObject::DelegateTest);
break;
case EDelegateType::SP: //绑定智能指针,会智能释放
if(!RawObjectPtr.IsValid())
{
RawObjectPtr = MakeShareable(new RawObject);
}
Delegate.BindSP(RawObjectPtr.ToSharedRef(), &RawObject::DelegateTest);
break;
case EDelegateType::Static: //绑定静态函数
Delegate.BindStatic(&&RawObject::DelegateStatic);
break;
case EDelegateType::UFunction: //绑定UE4对象,特点是用名字(字符串)找到函数,方法需要加UFUNCTION()宏
if(UEObject == nullptr)
{
UEObject = NewObject<UDelegateObject>();
}
Delegate.BindUFunction(UEObject, "TestDelegateUFunction");
break;
case EDelegateType::WeakLambda: //4.21新加的弱Lambda表达式,在执行时,会先检查 UEObject 的指针,如果指针失效了就不会执行Lambda表达式
if(UEObject == nullptr)
{
UEObject = NewObject<UDelegateObject>();
}
Delegate.BindWeakLambda(UEObject, []{void}{
UE_LOG(LogTemp, Warning, TEXT(_FUNCTION_));
});
break;
default:
break;
}
}
委托调用
if(Maker == nullptr)
{
Maker = NewObject<UDelegateMaker>();
}
Maker -> MakeDelegate(Type).ExecutelfBound();