From 7c47e172a728ad7a9d01dabdbcbc32fffbb63359 Mon Sep 17 00:00:00 2001 From: "Eunki, Hong" Date: Fri, 27 Oct 2023 18:47:55 +0900 Subject: [PATCH] Resolve DisposeRecursively crashed when we dispose scrollbase Due to some app's implements, ContentView can be disposed before ScrollBase itself disposed. In this case, ContentView is not null. So, when we try to call RemovePropertyNotification, it become crashed. To avoid these cases, let we make DisposeRecursively API makes more safety. And also, fix some crash issue in PerformanceTest1Page.xaml.cs what can be problem in future. Signed-off-by: Eunki, Hong --- src/Tizen.NUI.Components/Controls/ScrollableBase.cs | 5 ++++- src/Tizen.NUI/src/public/Common/Container.cs | 17 ++++++++++++----- .../PerformanceTest/PerformanceTest1Page.xaml.cs | 3 +-- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/Tizen.NUI.Components/Controls/ScrollableBase.cs b/src/Tizen.NUI.Components/Controls/ScrollableBase.cs index 6ecd82d..b2cecd8 100755 --- a/src/Tizen.NUI.Components/Controls/ScrollableBase.cs +++ b/src/Tizen.NUI.Components/Controls/ScrollableBase.cs @@ -1388,7 +1388,10 @@ namespace Tizen.NUI.Components mPanGestureDetector?.Dispose(); mPanGestureDetector = null; - ContentContainer?.RemovePropertyNotification(propertyNotification); + if(!(ContentContainer?.Disposed ?? true) && propertyNotification != null) + { + ContentContainer?.RemovePropertyNotification(propertyNotification); + } propertyNotification?.Dispose(); propertyNotification = null; } diff --git a/src/Tizen.NUI/src/public/Common/Container.cs b/src/Tizen.NUI/src/public/Common/Container.cs index fdfbf2c..9c85ac4 100755 --- a/src/Tizen.NUI/src/public/Common/Container.cs +++ b/src/Tizen.NUI/src/public/Common/Container.cs @@ -18,6 +18,7 @@ using System; using System.Collections.Generic; using System.ComponentModel; +using System.Linq; using Tizen.NUI.BaseComponents; using Tizen.NUI.Binding; using Tizen.NUI.Binding.Internals; @@ -249,18 +250,24 @@ namespace Tizen.NUI public void DisposeRecursively() { // To avoid useless "OnChildRemoved" callback invoke, Dispose itself before children. - if(!Disposed && !IsDisposeQueued) + if (!Disposed && !IsDisposeQueued) { Dispose(); } - foreach (View child in Children) - { - child.DisposeRecursively(); - } + // Copy child referecen to avoid Children changed during DisposeRecursively(); + var copiedChildren = childViews.ToList(); // Make sure that itself don't have children anymore. childViews?.Clear(); + + foreach (View child in copiedChildren) + { + if (!(child?.Disposed ?? true)) + { + child.DisposeRecursively(); + } + } } /// diff --git a/test/NUITizenGallery/Examples/PerformanceTest/PerformanceTest1Page.xaml.cs b/test/NUITizenGallery/Examples/PerformanceTest/PerformanceTest1Page.xaml.cs index 2600777..4fb0efd 100644 --- a/test/NUITizenGallery/Examples/PerformanceTest/PerformanceTest1Page.xaml.cs +++ b/test/NUITizenGallery/Examples/PerformanceTest/PerformanceTest1Page.xaml.cs @@ -98,8 +98,6 @@ namespace NUITizenGallery protected override void Dispose(DisposeTypes type) { - AppWindow.RemoveFrameUpdateCallback(FPSCounter); - if (Disposed) { return; @@ -107,6 +105,7 @@ namespace NUITizenGallery if (type == DisposeTypes.Explicit) { + AppWindow.RemoveFrameUpdateCallback(FPSCounter); RemoveAllChildren(true); } -- 2.7.4