JSBinding / Memory Management (GC)
C# and JavaScript both have Garbage Collection (GC). They should not conflict with each other.
Class type object
Class is reference type. We maintain a Map<> to store one-to-one relationship between C# class object and corresponding JavaScript object.
An example:
// C# List<int> lst = new List<int>(); // JavaScript (Compiled from C#) var lst = new System.Collections.Generic.List$1.ctor(System.Int32.ctor);
The process of returning a C# class object to JavaScript is:
1) C# gets JavaScript object ID from JavaScripit.
// File: System_Collections_Generic_List77.javascript _jstype.definition.ctor = function(t0) { CS.Call(5, 249, 0, true, this, t0.getNativeType()); } // 1) Here, 'this' will be passed to C#,C# wil get an ID (an int value representing JavaScript object)
2) C# creates a List<T> object (T is from JavaScript). See code below, Line14.
// System_Collection_Generic_List77Generated.cs
1 static bool ListA1_ListA11(JSVCall vc, int argc) 2 { 3 int _this = JSApi.getObject((int)JSApi.GetType.Arg); // we have JavaScript object here! 4 JSApi.attachFinalizerObject(_this); // (4) 5 --argc; 6 7 ConstructorInfo constructor = JSDataExchangeMgr.makeGenericConstructor(typeof(System.Collections.Generic.List<>), constructorID0); 8 if (constructor == null) return true; 9 10 int len = argc - 1; 11 if (len == 0) 12 { 13 JSMgr.addJSCSRel(_this, // (3) 14 constructor.Invoke(null, new object[]{}) // (2) 15 ); 16 } 17 18 return true; 19 }
3) C# stores one-to-one relationship. see code above, line 13.
NOTE: we store List<> object, and this object must be removed from map some time later, otherwise it will never be collected by C# GC.
4) Register a C# finalizer callback for JavaScript object, when it is collected by JavaScript GC, C# will be notified, and will remove the one-to-one relationship in C# map. See code above, Line 4.
5) Any time we want to return a C# object to JavaScript, we will first search the map, if corresponding JavaScript already exists, we simply return it. Otherwise we create and return a new JavaScript object. In this example, we already have a JavaScript (Line 3), so we don't need to create a new one.
Summary
for class type object, we will store C# object and JavaScript object relationship to a map. JavaScript object's life cycle is controlled by JavaScript GC, and C# object is removed when that JavaScript is collected.
Value type object (struct)
struct is value type. It's not possible to create a one-to-one relationship. When we want to return a C# struct to JavaScript, we always create a new one. And the relationship is: it's OK to find C# struct by JavaScript object ID, but it's not possible to find a JavaScript object by C# struct object.
map1[jsObjID] = csObj; // YES // map2[csObj.hashCode] = jsObjID; // NO
C# object is removed when JavaScript object is collected. (exactly as class object).
posted on 2015-07-30 21:54 AnswerWinner 阅读(352) 评论(0) 编辑 收藏 举报