Open fdcumt opened 4 years ago
在DelegateHelp中, 是通过一个全局Map, Delegate指针到DelegateDesc的映射, 来查找对应Delegate的具体类型的.
void FDelegateHelper::PreAdd(FMulticastDelegateType *ScriptDelegate, FMulticastDelegateProperty *Property) { check(ScriptDelegate && Property); FMulticastDelegateProperty **PropertyPtr = MulticastDelegate2Property.Find(ScriptDelegate); if (!PropertyPtr) { MulticastDelegate2Property.Add(ScriptDelegate, Property); } }
如果ScriptDelegate在MulticastDelegate2Property中存在, 就不做任何操作. 但是在电脑上(目前在电脑上复现过,手机上不确定,理论上有可能),当UE内存重用(UE是自己进行内存管理的,内存重用发生概率很高.), 指针的值(也就是内存逻辑地址)就很有可能发生重复的情况, 当重复后, 就注册不进去了. 如果原来的类型和新类型一致, 那么不会报错, 如果不一致,就会导致类型错误. 即当两个地址相同,但类型不同的Delegate先后注册的时候, 就会发生错误.
修改方法:去重检测
if (!PropertyPtr || !*PropertyPtr || (*PropertyPtr)->GetName()!=Property->GetName()) { MulticastDelegate2Property.Add(ScriptDelegate, Property); }
理论上FDelegateHelper::PreBind也会遇到同样的问题,但是我这里没有遇到过crash,暂时先不改了.
void FDelegateHelper::PreBind(FScriptDelegate *ScriptDelegate, FDelegateProperty *Property) { check(ScriptDelegate && Property); FDelegateProperty **PropertyPtr = Delegate2Property.Find(ScriptDelegate); if (!PropertyPtr) { Delegate2Property.Add(ScriptDelegate, Property); } }
这个是UFunction被GC了, 还没查到为啥
ScriptDelegate地址重了,说明前一个内存已经被释放了,此时访问Property可能访问到脏地址。我想有没有办法及时清理掉被释放的ScriptDelegate?
在DelegateHelp中, 是通过一个全局Map, Delegate指针到DelegateDesc的映射, 来查找对应Delegate的具体类型的.
如果ScriptDelegate在MulticastDelegate2Property中存在, 就不做任何操作. 但是在电脑上(目前在电脑上复现过,手机上不确定,理论上有可能),当UE内存重用(UE是自己进行内存管理的,内存重用发生概率很高.), 指针的值(也就是内存逻辑地址)就很有可能发生重复的情况, 当重复后, 就注册不进去了. 如果原来的类型和新类型一致, 那么不会报错, 如果不一致,就会导致类型错误. 即当两个地址相同,但类型不同的Delegate先后注册的时候, 就会发生错误.
修改方法:去重检测
理论上FDelegateHelper::PreBind也会遇到同样的问题,但是我这里没有遇到过crash,暂时先不改了.