WeakReference for parent

Summary: - Use WeakReference for parent to avoid circular reference although GC will treat it

Reviewed By: emilsjolander

Differential Revision: D3982520

fbshipit-source-id: b0f6764aa4df3da53be51f6cb4fe2994d989afdf
This commit is contained in:
Kazuki Sakamoto
2016-10-07 11:07:51 -07:00
committed by Facebook Github Bot
parent c233bafeb2
commit 90844d62c5
2 changed files with 44 additions and 5 deletions

View File

@@ -19,7 +19,7 @@ namespace Facebook.CSSLayout
private bool _isDisposed; private bool _isDisposed;
private IntPtr _cssNode; private IntPtr _cssNode;
private CSSNode _parent; private WeakReference _parent;
private List<CSSNode> _children; private List<CSSNode> _children;
private MeasureFunction _measureFunction; private MeasureFunction _measureFunction;
private CSSMeasureFunc _measureFunc; private CSSMeasureFunc _measureFunc;
@@ -155,7 +155,7 @@ namespace Facebook.CSSLayout
get get
{ {
AssertNativeInstance(); AssertNativeInstance();
return _parent; return _parent != null ? _parent.Target as CSSNode : null;
} }
} }
@@ -632,7 +632,7 @@ namespace Facebook.CSSLayout
{ {
AssertNativeInstance(); AssertNativeInstance();
_children.Insert(index, node); _children.Insert(index, node);
node._parent = this; node._parent = new WeakReference(this);
Native.CSSNodeInsertChild(_cssNode, node._cssNode, (uint)index); Native.CSSNodeInsertChild(_cssNode, node._cssNode, (uint)index);
} }

View File

@@ -117,12 +117,12 @@ namespace Facebook.CSSLayout
{ {
ForceGC(); ForceGC();
Assert.AreEqual(0, CSSNode.GetInstanceCount()); Assert.AreEqual(0, CSSNode.GetInstanceCount());
TestDestructorFunc(); TestDestructorForGC();
ForceGC(); ForceGC();
Assert.AreEqual(0, CSSNode.GetInstanceCount()); Assert.AreEqual(0, CSSNode.GetInstanceCount());
} }
private void TestDestructorFunc() private void TestDestructorForGC()
{ {
CSSNode node = new CSSNode(); CSSNode node = new CSSNode();
Assert.AreEqual(0, CSSNode.GetInstanceCount()); Assert.AreEqual(0, CSSNode.GetInstanceCount());
@@ -131,6 +131,45 @@ namespace Facebook.CSSLayout
node = null; node = null;
} }
[Test]
public void TestDestructorWithChildren()
{
ForceGC();
Assert.AreEqual(0, CSSNode.GetInstanceCount());
TestDestructorWithChildrenForGC1();
ForceGC();
Assert.AreEqual(0, CSSNode.GetInstanceCount());
}
private void TestDestructorWithChildrenForGC1()
{
CSSNode node = new CSSNode();
Assert.AreEqual(0, CSSNode.GetInstanceCount());
node.Initialize();
Assert.AreEqual(1, CSSNode.GetInstanceCount());
TestDestructorWithChildrenForGC2(node, 1);
ForceGC();
Assert.AreEqual(2, CSSNode.GetInstanceCount());
TestDestructorWithChildrenForGC2(node, 2);
ForceGC();
Assert.AreEqual(3, CSSNode.GetInstanceCount());
node = null;
}
private void TestDestructorWithChildrenForGC2(CSSNode parent, int count)
{
CSSNode child = new CSSNode();
Assert.AreEqual(count, CSSNode.GetInstanceCount());
child.Initialize();
Assert.AreEqual(count + 1, CSSNode.GetInstanceCount());
parent.Insert(0, child);
child = null;
}
private void ForceGC() private void ForceGC()
{ {
GC.Collect(GC.MaxGeneration); GC.Collect(GC.MaxGeneration);