UE4委託
01 委託(代理)
委託,又稱代理,本質是一個特殊類的物件,它內部可以儲存(一個或多個)函式指標、呼叫引數和返回值。
委託的作用如同函式指標,但它更安全(支援編譯期型別檢查),而且更易於使用。
使用委託,通過對委託的一個執行就可以呼叫到物件的函式。
02 概念
代理:在你不知道物件是什麼的時候,也可以執行物件中的函式,delegate代理為兩個物件之間建立起了通訊,當我需要呼叫物件中的成員時,可我們不知道物件是誰,這時只需要打電話給這個中介delegate即可。委託的功能類似與藍圖中的發報機。
代理主要有三個特性:繫結、呼叫、解除繫結。
03 UE4支援代理型別
- 單播代理:支援繫結單個函式
- 多播代理:支援繫結多個函式
- 動態代理:可序列化的Uobject
04 單播代理的使用
主要的代理型別有四種:
- 不帶形參,不帶返回值
- 帶形參,不帶返回值
- 帶返回值,不帶形參
- 帶返回值,帶形參的
代理建立方式:
虛幻4有著自己定義的一套delegate,需要通過delegate巨集建立。
//宣告委託 不帶形參,不帶返回值(它可以繫結的這個函式必須是沒有引數也沒有返回值的)
DECLARE_DELEGATE(FDelegateTestA);
//宣告委託 帶形參,不帶返回值,類似的一共有9個巨集,最大帶9個形參 如:DECLARE_DELEGATE_NineParams
DECLARE_DELEGATE_OneParam(FDelegateTestB,bool);
//宣告委託帶 帶返回值,不帶形參
DECLARE_DELEGATE_RetVal(bool,FDelegateTestC);
//宣告委託 帶返回值,帶形參的,類似的一共有9個巨集,最大帶9個形參 如:DECLARE_DELEGATE_NineParams
DECLARE_DELEGATE_RetVal_OneParam(int32,FDelegateTestD,FString&);
目前虛幻4巨集最多可以帶9個形參,如:DECLARE_DELEGATE_OneParam一直到DECLARE_DELEGATE_NineParams
單播代理案列:不帶引數的代理,繫結C++原生類
繫結UE4物件,後面是繫結的函式
先宣告兩個類並繫結代理
#include "CoreMinimal.h"
//宣告委託
DECLARE_DELEGATE(FDelegateTestA);
//宣告ClassA類
class ClassA
{
public:
//宣告代理
FDelegateTestA DelegateTestA;
//呼叫代理
void Eexcute()
{
//呼叫代理,先判斷是否繫結了,繫結上了再執行代理。
DelegateTestA.ExecuteIfBound();
}
};
//宣告ClassB類
class ClassB
{
public:
//建構函式,繫結代理
ClassB(ClassA* NewClass_a)
if (NewClass_a)
{
m_classA = NewClass_a;
m_classA->DelegateTestA.BindRaw(this, &ClassB::ExecuteA);//繫結事件ExecuteA
}
void ExecuteA()
{
Print_F(TEXT("Hello world"));
}
//解構函式,解除繫結
~ClassB()
{
if (m_classA)
{
m_classA->DelegateTestA.Unbind();
m_classA->Execute();
delete m_classA;
m_classA = nullptr;
}
private:
ClassA* m_classA;
};
呼叫代理
//假設為程式入口
void BeginPlay()
{
//建立ClassA指標
ClassA* NewClassA = new ClassA();
//建立ClassB指標,構建函式
ClassB* NewClassB = new ClassB(NewClassA);
//呼叫代理Execute(),Execute會呼叫ClassB中的Execute()A函式
//NewClassA不知道有物件NewClassB的,存在卻可以呼叫NewClassB的成員
//代理為ClassA類和ClassB之間建立通訊
NewClassA->Execute();
//釋放指
delete NewClassB;
NewClassA = nullptr;
NewClassB = nullptr;
}
結果
//螢幕會列印“Hello world”,ClassA在不知道物件ClassB情況下呼叫了ClassB的成員
05 動態代理的使用
動態委託可以序列化,其函式可按命名查詢,但其執行速度比常規委託慢。
宣告
DECLARE_DYNAMIC_DELEGATE[
繫結
輔助巨集 | 說明 |
---|---|
BindDynamic( UserObject, FuncName ) | 用於在動態委託上呼叫BindDynamic()的輔助巨集。自動生成函式命名字串。 |
執行
執行函式 | 描述 |
---|---|
Execute | 不檢查其繫結情況即執行一個委託 |
ExecuteIfBound | 檢查一個委託是否已繫結,如是,則呼叫Execute |
IsBound | 檢查一個委託是否已繫結,經常出現在包含 Execute 呼叫的程式碼前 |
06 多播代理的使用
多播委託擁有大部分與單播委託相同的功能。它們只擁有對物件的弱引用,可以與結構體一起使用,可以四處輕鬆複製等等。
就像常規委託一樣,多播委託可以遠端載入/儲存和觸發;但多播委託函式不能使用返回值。它們最適合用來 四處輕鬆傳遞一組委託。
事件是一種特殊型別的多播委託,它在訪問"Broadcast()"、"IsBound()"和"Clear()"函式時會受到限制。
宣告
宣告巨集 | 說明 |
---|---|
DECLARE_MULTICAST_DELEGATE[_RetVal, ...]( DelegateName ) | 建立一個多播委託。 |
DECLARE_DYNAMIC_MULTICAST_DELEGATE[_RetVal, ...]( DelegateName ) | 建立一個動態多播委託。 |
繫結
多播委託可以繫結多個函式,當委託觸發時,將呼叫所有這些函式。因此,繫結函式在語義上與陣列更加類似。
函式 | 說明 |
---|---|
“Add()” | 將函式委託新增到該多播委託的呼叫列表中。 |
“AddStatic()” | 新增原始C++指標全域性函式委託。 |
“AddRaw()” | 新增原始C++指標委託。原始指標不使用任何型別的引用,因此如果從委託下面刪除了物件,則呼叫此函式可能不安全。呼叫Execute()時請小心! |
“AddSP()” | 新增基於共享指標的(快速、非執行緒安全)成員函式委託。共享指標委託保留對物件的弱引用。 |
“AddUObject()” | 新增基於UObject的成員函式委託。UObject委託保留對物件的弱引用。 |
“Remove()” | 從該多播委託的呼叫列表中刪除函式(效能為O(N))。請注意,委託的順序可能不會被保留! |
“RemoveAll()” | 從該多播委託的呼叫列表中刪除繫結到指定UserObject的所有函式。請注意,委託的順序可能不會被保留! |
"RemoveAll()"將刪除繫結到所提供指標的所有已註冊委託。切記,未繫結到物件指標的原始委託不會被該函式所刪除!
執行
多播委託允許您附加多個函式委託,然後通過呼叫多播委託的"Broadcast()"函式一次性同時執行它們。多播委託簽名不得使用返回值。
在多播委託上呼叫"Broadcast()"總是安全的,即使是在沒有任何繫結時也是如此。唯一需要注意的是,如果您使用委託來初始化輸出變數,通常會帶來非常不利的後果。
呼叫"Broadcast()"時繫結函式的執行順序尚未定義。執行順序可能與函式的新增順序不相同。
函式 | 說明 |
---|---|
“Broadcast()” | 將該委託廣播給所有繫結的物件,但可能已過期的物件除外。 |
相關文章
- 委託
- # 委託
- 委託與事件-委託詳解(一)事件
- 事件委託事件
- Java-委託Java
- C#委託C#
- 行為委託
- C# 委託(delegate)、泛型委託和Lambda表示式C#泛型
- dotnet 委託的實現解析(2)開放委託和封閉委託 (Open Delegates vs. Closed Delegates)
- wpf移除事件委託事件
- 04.委託Delegation
- 委託的好處
- winform實現委託ORM
- C#-委託delegateC#
- Kotlin基礎 — 委託Kotlin
- js中的事件委託JS事件
- c#中的委託C#
- c# 委託和事件C#事件
- C# - 委託與事件C#事件
- C#委託與事件C#事件
- 事件模型和事件委託事件模型
- 優化委託的 `DynamicInvoke`優化
- C#的委託案例C#
- JQuery7:事件委託jQuery事件
- C#委託理解(1)C#
- 瞭解下C# 委託(Delegate)C#
- dotnet 委託的實現解析
- Js 事件原理與事件委託JS事件
- 簡單多播委託Demo
- 事件的捕獲、冒泡、委託事件
- JS事件流和事件委託JS事件
- ios中的多播委託iOS
- C#基礎之委託,事件C#事件
- 詳解C#委託與事件C#事件
- 委託與事件-事件詳解(二)事件
- System.Linq.Dynamic字串轉委託字串
- 委託、匿名方法到lambda表示式
- .NET委託,事件和Lambda表示式事件