Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

某个 UObject 如果不再被 Lua 引用,它在 Lua 添加的委托函数就会失效 #394

Closed
GotGimhong opened this issue Apr 13, 2022 · 1 comment

Comments

@GotGimhong
Copy link
Contributor

测试样例如下,首先在 C++ 定义一个 UObject,它使用单例模式,包含一个委托,然后在 Lua 添加委托函数:

UCLASS()
class UMyObject : public UObject
{
    GENERATED_BODY()

public:
    UFUNCTION(BlueprintCallable)
    static UMyObject* GetSingleton()
    {
        return GetMutableDefault<UMyObject>();
    }

public:
    DECLARE_DYNAMIC_MULTICAST_DELEGATE(FMyDelegate);
    UPROPERTY(BlueprintAssignable)
    FMyDelegate MyDelegate;
};
-- 添加委托函数
function RegisterDelegate()
    local myObject = UE.UMyObject.GetSingleton()
    myObject.MyDelegate:Add(myObject, OnMyDelegateBroadcast)
end

-- 移除委托函数
function UnregisterDelegate()
    local myObject = UE.UMyObject.GetSingleton()
    myObject.MyDelegate:Remove(myObject, OnMyDelegateBroadcast)
end

function OnMyDelegateBroadcast()
    ...
end

经过测试,我们发现了两个问题:

  1. MyDelegate 广播的时候,Lua 的 OnMyDelegateBroadcast 函数并没有执行
  2. Lua 的 UnregisterDelegate 函数执行之后,MyDelegate 绑定的委托函数并没有移除

这两个问题似乎都来源于同一个问题。在 Lua 的 RegisterDelegate 函数当中,其实是先创建了 UMyObject 类单例的一个临时引用,然后再释放这个引用。我们发现临时引用被释放后,会触发 C++ 的 UObject_Delete 函数,调用栈如下:

  1. UObject_Delete,Lualib_Object.cpp 第335行
  2. DeleteUObjectRefs,LuaCore.cpp 第1048行
  3. FDelegateHelper::Remove,DelegateHelper.cpp 第332行
  4. FSignatureDesc::MarkForDelete,DelegateHelper.cpp 第37行
  5. FDelegateHelper::CleanUpByFunction,DelegateHelper.cpp 第463行

也就是说,一旦 Lua 不再引用某个 UObject,它所绑定的委托函数,就会从 FDelegateHelper::Callback2Function 当中被清理掉。这样一来,委托函数自然就执行不到了,另外当真正想要在 Lua 移除委托函数的时候,也因为无法在 FDelegateHelper::Callback2Function 当中找到绑定记录而移除失败。

@xuyanghuang-tencent xuyanghuang-tencent added the pending release This will be released on next version label May 5, 2022
@xuyanghuang-tencent
Copy link
Collaborator

v2.2.0

@xuyanghuang-tencent xuyanghuang-tencent removed the pending release This will be released on next version label Nov 7, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants