static IntPtr RetainTrampoline(IntPtr @this, IntPtr sel) { int ref_count = Messaging.int_objc_msgSend(@this, Selector.RetainCount); NSObject obj = null; #if DEBUG_REF_COUNTING bool had_managed_ref = HasManagedRef(@this); int pre_gchandle = GetGCHandle(@this); #endif /* * We need to decide if the gchandle should become a strong one. * This happens if managed code has a ref, and the current refcount is 1. */ if (ref_count == 1) { obj = Runtime.TryGetNSObject(@this); if (obj != null && obj.has_managed_ref) { obj.SwitchGCHandle(false /* strong */); } } @this = InvokeObjCMethodImplementation(@this, sel); #if DEBUG_REF_COUNTING Console.WriteLine("RetainTrampoline ({0} Handle=0x{1}) initial retainCount={2}; new retainCount={3} HadManagedRef={4} HasManagedRef={5} old GCHandle={6} new GCHandle={7}", Class.GetName(Messaging.intptr_objc_msgSend(@this, Selector.GetHandle("class"))), @this.ToString("x"), ref_count, Messaging.int_objc_msgSend(@this, Selector.RetainCount), had_managed_ref, HasManagedRef(@this), pre_gchandle, GetGCHandle(@this)); #endif return(@this); }
static void ReleaseTrampoline(IntPtr @this, IntPtr sel) { int ref_count = Messaging.int_objc_msgSend(@this, Selector.RetainCount); NSObject obj = null; #if DEBUG_REF_COUNTING Console.WriteLine("ReleaseTrampoline ({0} Handle=0x{1}) retainCount={2}; HasManagedRef={3} GCHandle={4}", GetClassName(@this), @this.ToString("x"), ref_count, HasManagedRef(@this), GetGCHandle(@this)); #endif /* Object is about to die. Unregister it and free any gchandles we may have */ if (ref_count == 1) { obj = Runtime.TryGetNSObject(@this); if (obj != null) { obj.UnregisterObject(); obj.FreeGCHandle(); } else { #if DEBUG_REF_COUNTING Console.WriteLine("\tCould not find managed object"); #endif } } /* * We need to decide if the gchandle should become a weak one. * This happens if managed code will end up holding the only ref. */ if (ref_count == 2) { obj = Runtime.TryGetNSObject(@this); if (obj != null && obj.has_managed_ref) { obj.SwitchGCHandle(true /* weak */); } } InvokeObjCMethodImplementation(@this, sel); }