diff options
author | Stephane Delcroix <stephane@delcroix.org> | 2016-12-06 13:15:32 +0100 |
---|---|---|
committer | Rui Marinho <me@ruimarinho.net> | 2016-12-06 12:15:32 +0000 |
commit | 20e2e12dce2f81b92e8682f128cd81e08469f485 (patch) | |
tree | 965f0715dc24af3c0d0bd17740da9d962ed12927 | |
parent | 10c65d035869fdc587f6ddddc0d472033af61ee6 (diff) | |
download | xamarin-forms-20e2e12dce2f81b92e8682f128cd81e08469f485.tar.gz xamarin-forms-20e2e12dce2f81b92e8682f128cd81e08469f485.tar.bz2 xamarin-forms-20e2e12dce2f81b92e8682f128cd81e08469f485.zip |
[C] detach Behaviors and Triggers on VE finalization (#555)
* [C] detach Behaviors and Triggers on VE finalization
* update docs
-rw-r--r-- | Xamarin.Forms.Core.UnitTests/BehaviorTest.cs | 42 | ||||
-rw-r--r-- | Xamarin.Forms.Core/BindableObject.cs | 8 | ||||
-rw-r--r-- | Xamarin.Forms.Core/VisualElement.cs | 13 | ||||
-rw-r--r-- | docs/Xamarin.Forms.Core/Xamarin.Forms/VisualElement.xml | 16 |
4 files changed, 78 insertions, 1 deletions
diff --git a/Xamarin.Forms.Core.UnitTests/BehaviorTest.cs b/Xamarin.Forms.Core.UnitTests/BehaviorTest.cs index 78e0cfb0..90217389 100644 --- a/Xamarin.Forms.Core.UnitTests/BehaviorTest.cs +++ b/Xamarin.Forms.Core.UnitTests/BehaviorTest.cs @@ -3,8 +3,9 @@ using NUnit.Framework; namespace Xamarin.Forms.Core.UnitTests { - internal class MockBehavior<T> : Behavior<T> where T:BindableObject + class MockBehavior<T> : Behavior<T> where T:BindableObject { + public static int AttachCount { get; set; } public bool attached; public bool detached; @@ -12,11 +13,13 @@ namespace Xamarin.Forms.Core.UnitTests { base.OnAttachedTo (bindable); attached = true; + AttachCount++; AssociatedObject = bindable; } protected override void OnDetachingFrom (BindableObject bindable) { + AttachCount--; detached = true; base.OnDetachingFrom (bindable); AssociatedObject = null; @@ -106,5 +109,42 @@ namespace Xamarin.Forms.Core.UnitTests collection.Remove (behavior); Assert.Null (behavior.AssociatedObject); } + + [Test] + //https://bugzilla.xamarin.com/show_bug.cgi?id=44074 + public void TestBehaviorsAreDetachedBeforeGarbageCollection() + { + WeakReference weakBindable = null; + + var attachCount = MockBehavior<VisualElement>.AttachCount; + + int i = 0; + Action create = null; + create = () => + { + if (i++ < 1024) + { + create(); + return; + } + + var bindable = new MockBindable + { + Behaviors = { + new MockBehavior<VisualElement> () + } + }; + weakBindable = new WeakReference(bindable); + }; + + create(); + + GC.Collect(); + GC.WaitForPendingFinalizers(); + GC.Collect(); + + Assert.False(weakBindable.IsAlive); + Assert.AreEqual(attachCount, MockBehavior<VisualElement>.AttachCount); + } } }
\ No newline at end of file diff --git a/Xamarin.Forms.Core/BindableObject.cs b/Xamarin.Forms.Core/BindableObject.cs index 217f4a94..b5e41452 100644 --- a/Xamarin.Forms.Core/BindableObject.cs +++ b/Xamarin.Forms.Core/BindableObject.cs @@ -163,6 +163,14 @@ namespace Xamarin.Forms return bpcontext != null && bpcontext.Binding != null; } + internal bool GetIsDefault(BindableProperty targetProperty) + { + if (targetProperty == null) + throw new ArgumentNullException(nameof(targetProperty)); + + return GetContext(targetProperty) == null; + } + internal object[] GetValues(BindableProperty property0, BindableProperty property1) { var values = new object[2]; diff --git a/Xamarin.Forms.Core/VisualElement.cs b/Xamarin.Forms.Core/VisualElement.cs index 053ddb0a..cff1eb10 100644 --- a/Xamarin.Forms.Core/VisualElement.cs +++ b/Xamarin.Forms.Core/VisualElement.cs @@ -781,5 +781,18 @@ namespace Xamarin.Forms public bool Result { get; set; } } + + ~VisualElement() + { + if (!GetIsDefault(BehaviorsProperty)) { + var behaviors = GetValue(BehaviorsProperty) as AttachedCollection<Behavior>; + behaviors.DetachFrom(this); + } + + if (!GetIsDefault(TriggersProperty)) { + var triggers = GetValue(TriggersProperty) as AttachedCollection<Trigger>; + triggers.DetachFrom(this); + } + } } }
\ No newline at end of file diff --git a/docs/Xamarin.Forms.Core/Xamarin.Forms/VisualElement.xml b/docs/Xamarin.Forms.Core/Xamarin.Forms/VisualElement.xml index 426d8c60..9b28bf08 100644 --- a/docs/Xamarin.Forms.Core/Xamarin.Forms/VisualElement.xml +++ b/docs/Xamarin.Forms.Core/Xamarin.Forms/VisualElement.xml @@ -290,6 +290,22 @@ </remarks> </Docs> </Member> + <Member MemberName="Finalize"> + <MemberSignature Language="C#" Value="~VisualElement ();" /> + <MemberSignature Language="ILAsm" Value=".method familyhidebysig virtual instance void Finalize() cil managed" /> + <MemberType>Method</MemberType> + <AssemblyInfo> + <AssemblyVersion>2.0.0.0</AssemblyVersion> + </AssemblyInfo> + <ReturnValue> + <ReturnType>System.Void</ReturnType> + </ReturnValue> + <Parameters /> + <Docs> + <summary>To be added.</summary> + <remarks>To be added.</remarks> + </Docs> + </Member> <Member MemberName="Focus"> <MemberSignature Language="C#" Value="public bool Focus ();" /> <MemberSignature Language="ILAsm" Value=".method public hidebysig instance bool Focus() cil managed" /> |