From: E.Z. Hart Date: Thu, 24 Oct 2019 17:47:05 +0000 (-0600) Subject: Occasionally clean up WeakReferences in Styles whose targets have been collected... X-Git-Tag: accepted/tizen/5.5/unified/20200421.150457~81^2~1^2~14 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=bd82891e3e4c14a2d5ee4b9dd9de6d80ebb67424;p=platform%2Fcore%2Fcsapi%2Fxsf.git Occasionally clean up WeakReferences in Styles whose targets have been collected (#8124) --- diff --git a/Xamarin.Forms.Core/Interactivity/AttachedCollection.cs b/Xamarin.Forms.Core/Interactivity/AttachedCollection.cs index e2f420b..1acb7a1 100644 --- a/Xamarin.Forms.Core/Interactivity/AttachedCollection.cs +++ b/Xamarin.Forms.Core/Interactivity/AttachedCollection.cs @@ -8,6 +8,9 @@ namespace Xamarin.Forms { readonly List _associatedObjects = new List(); + const int CleanupTrigger = 128; + int _cleanupThreshold = CleanupTrigger; + public AttachedCollection() { } @@ -64,6 +67,7 @@ namespace Xamarin.Forms lock (_associatedObjects) { _associatedObjects.Add(new WeakReference(bindable)); + CleanUpWeakReferences(); } foreach (T item in this) item.AttachTo(bindable); @@ -123,5 +127,16 @@ namespace Xamarin.Forms item.AttachTo(bindable); } } + + void CleanUpWeakReferences() + { + if (_associatedObjects.Count < _cleanupThreshold) + { + return; + } + + _associatedObjects.RemoveAll(t => !t.IsAlive); + _cleanupThreshold = _associatedObjects.Count + CleanupTrigger; + } } } \ No newline at end of file diff --git a/Xamarin.Forms.Core/Style.cs b/Xamarin.Forms.Core/Style.cs index b6ee911..7adbc1e 100644 --- a/Xamarin.Forms.Core/Style.cs +++ b/Xamarin.Forms.Core/Style.cs @@ -10,6 +10,9 @@ namespace Xamarin.Forms { internal const string StyleClassPrefix = "Xamarin.Forms.StyleClass."; + const int CleanupTrigger = 128; + int _cleanupThreshold = CleanupTrigger; + readonly BindableProperty _basedOnResourceProperty = BindableProperty.CreateAttached("BasedOnResource", typeof(Style), typeof(Style), default(Style), propertyChanged: OnBasedOnResourceChanged); @@ -93,6 +96,8 @@ namespace Xamarin.Forms if (BaseResourceKey != null) bindable.SetDynamicResource(_basedOnResourceProperty, BaseResourceKey); ApplyCore(bindable, BasedOn ?? GetBasedOnResource(bindable)); + + CleanUpWeakReferences(); } public Type TargetType { get; } @@ -178,5 +183,16 @@ namespace Xamarin.Forms return true; return value.TargetType.IsAssignableFrom(TargetType); } + + void CleanUpWeakReferences() + { + if (_targets.Count < _cleanupThreshold) + { + return; + } + + _targets.RemoveAll(t => !t.TryGetTarget(out _)); + _cleanupThreshold = _targets.Count + CleanupTrigger; + } } } \ No newline at end of file