if 组件是否存在_UE4 UMG简介+Slate组件问题排查
Slate 組件問題排查總結簡介
首先是一個工作中遇到的BUG: 用slua添加子節點到父節點上的時候,第二次打開無法顯示對應的子節點Widget。對應Lua代碼如下
因為我們引入了UI對象的內存池概念,很自然而然的想到了緩存住的控件是不是釋放有問題。檢查slua的release代碼之后發現沒有任何問題。基于ScaleBox 只能有1個子物體這一個機制,在猜測BUG原因的時候,嘗試用CanvasPanel替換ScaleBox組件。發現果然能解決這個問題。
但是也帶來了2個新問題:
1、ScaleBox子物體在第一次關閉和第二次打開的時候經歷了什么?
2、為什么CanvasPanel就可以而ScaleBox不可以?
為了解決以上疑問,開啟我們的排查過程。
為了能使大家更好的了解這個流程,先對Slate組件創建銷毀流程進行介紹。Slate組件創建銷毀流程
1、將我們日常使用的一個組件,ScaleBox拆出來看(如下圖):有如下的對應關系。里面包含了 UScaleBox,UScaleBoxSlot,SscaleBox 。
2、創建過程
3、銷毀過程
問題排查
針對ScaleBox,進入斷點調試。
在第一次關閉界面的時候,發現UscaleBox Release 有正常跑到(下面代碼部分)。
但是在第二次打開的時候,發現沒有進入RebuildWidget(Swidget的實例化部分,也就是下面代碼部分)
這是為什么呢? 原來,在UWidget的BUILD過程中,有一個查找共享指針MyWidget的操作。這個指針雖然被UscaleBox Reset了一次。但是在ScaleBox 第二次打開時候,這個指針依然存在引用。所以該實例并沒有被銷毀。那么在第二次打開的時候,由于沒有走RebuildWidget。導致了子類UScaleBox 的指針引用已經被銷毀,在AddChild時候調用添加了個空Object。(下圖代碼部分)
那這個指針是被誰Hold住了呢? 經過排查與調試,發現是被UScaleBoxSlot給Hold住了導致了這份資源沒有被釋放。
為什么在UScaleBox中的共享指針已經釋放了,但是UScaleBoxSlot所持有的相同指針沒有被釋放呢?請看Slot釋放的地方(下面代碼模塊):
UE的注釋寫的很清楚了,我們所Add 的子物體,正是UserWidget 界面。在UE-39106版本中,讓UserWidget 的Slate釋放控制交給了上層。在這里沒有自動釋放。下面是UE 39106的改動鏈接。https://issues.unrealengine.com/issue/UE-39106
虛幻引擎UE為了補鍋一個slate 被釋放的問題,導致了這個新問題。 我們上層緩存了這份實例,銷毀子物體的時候調用了RemoveFromParent。在ScaleBox被銷毀的時候,因為其子物體為userwidget,而不去釋放PanelSlot的SlateResourse。那么在第二次打開的時候,因為PanelSlot中共享指針的存在,沒有New一份新的子物體實例。
OK,問題定位了。那么之前提到的第二個問題,為什么換成CanvasPanel就沒有這個問題了呢?,既然查到了在ScaleBox 中是 ScaleBoxSlot 的指針Hold住了這份資源,那么我們去CanvasPanel對應的Slot 看一下。(下面代碼)
明顯可以看出:原來CanvasPanelSlot 在Build過程中沒有緩存那份實例!只是做了常規引用!在上面有貼出過ScaleBoxSlot build 過程的代碼。所以就是ScaleBoxSlot 存住了這份指針,而CanvasPanelSlot 并沒有。所以在都沒有Release對應掉這份資源的情況下,CanvasPanel會走rebuild過程,而ScaleBox不會!
到這里,我們基本上就定位出了問題全部原因所在。解決辦法
這里想到了4種解決方案,都能解決這個問題,這里簡單說一下:
1、不判斷指針是否還存在引用,全部走Rebuild過程。
2、在Remove判斷是否為UserWidget過程中,對本身PanelSlot做一次釋放。
3、刪除UScaleBoxSlot中對SscaleBox指針的引用。
4、將UScaleBoxSlot中的共享引用改為弱引用。
第一種風險較大,因為所有UMG都會走的創建過程,不太保險。
第二種風險小于第一種,但是也在所有UMG都會走的創建過程,不太保險。
第三種和第四種個人感覺都是有效的方案,總的來看還是第四種改動小并優雅一點。
所以目前采用了第四種。
總結
以上是生活随笔為你收集整理的if 组件是否存在_UE4 UMG简介+Slate组件问题排查的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 下面哪个字段是http请求中必须具备的_
- 下一篇: 交通银行白金卡相关问题及分析
