예제 #1
0
        public void ToggleRef_NonToggledObjectsShouldBeCollected()
        {
            // This test verifies that toggleable objects that aren't toggled aren't kept alive.
            // We create a number of managed NSFileManager instance, get a native reference to each of them,
            // and then we verify that the managed instance is collected.
            var counter  = 100;
            var handles  = new GCHandle [counter];
            var pointers = new IntPtr [counter];

            var t = new Thread(() =>
            {
                for (var i = 0; i < counter; i++)
                {
                    var obj = new NSFileManager();
                    // do not toggle
                    obj.DangerousRetain();                      // obtain a native reference
                    handles [i]  = GCHandle.Alloc(obj, GCHandleType.Weak);
                    pointers [i] = obj.Handle;
                }
            })
            {
                IsBackground = true,
                Name         = "ToggleRef_NonToggledObjectsShouldBeCollected",
            };

            t.Start();
            Assert.IsTrue(t.Join(TimeSpan.FromSeconds(10)), "Background thread completion");

            var checkForCollectedManagedObjects = new Func <bool> (() =>
            {
                GC.Collect();
                GC.WaitForPendingFinalizers();
                for (var i = 0; i < counter; i++)
                {
                    if (handles [i].Target == null)
                    {
                        return(true);
                    }
                }
                return(false);
            });

            // Iterate over the runloop in case something has to happen on the main thread for the objects to be collected.
            TestRuntime.RunAsync(TimeSpan.FromSeconds(5), () => { }, checkForCollectedManagedObjects);

            Assert.IsTrue(checkForCollectedManagedObjects(), "Any collected objects");

            for (var i = 0; i < counter; i++)
            {
                var obj = Runtime.GetNSObject(pointers [i]);
                Assert.IsNotNull(obj, $"Object #{i} couldn't be resurrected");
                obj.DangerousRelease();                  // release the native reference
                obj.Dispose();
                handles [i].Free();
            }
        }
예제 #2
0
        public void ToggleRef_ToggledObjectsShouldNotBeCollected()
        {
            // This test verifies that toggleable objects that are toggled are kept alive while the native peer is alive.
            // We create a number of managed NSFileManager instance, get a native reference to each of them,
            // and then we verify that the managed instance won't be collected.
            //
            // NSFileManager instances are toggled when the [Weak]Delegate property is set.
            var del     = new NSFileManagerDelegate();
            var counter = 100;
            var handles = new GCHandle [counter];
            var t       = new Thread(() =>
            {
                for (var i = 0; i < counter; i++)
                {
                    var obj      = new NSFileManager();
                    obj.Delegate = del;                     // toggle
                    obj.DangerousRetain();                  // obtain a native reference
                    handles [i] = GCHandle.Alloc(obj, GCHandleType.Weak);
                }
            })
            {
                IsBackground = true,
                Name         = "ToggleRef_ToggledObjectsShouldNotBeCollected",
            };

            t.Start();
            Assert.IsTrue(t.Join(TimeSpan.FromSeconds(10)), "Background thread completion");

            TestRuntime.RunAsync(TimeSpan.FromSeconds(2), () => { }, () =>
            {
                // Iterate over the runloop a bit to make sure we're just not collecting because objects are queued on for things to happen on the main thread
                GC.Collect();
                GC.WaitForPendingFinalizers();
                return(false);
            });

            for (var i = 0; i < counter; i++)
            {
                var obj = (NSFileManager)handles [i].Target;
                Assert.IsNotNull(obj, $"Object #{i} was unexpectedly collected.");
                obj.DangerousRelease();                  // release the native reference
                obj.Dispose();
                handles [i].Free();
            }
        }