【问题标题】:Why can't MonoTouch GC kill managed objects with refcount > 1?为什么 MonoTouch GC 不能杀死 refcount > 1 的托管对象?
【发布时间】:2012-10-25 19:34:55
【问题描述】:

我想我已经接近理解how Mono GC and ObjC ref counting live together

它的工作方式是,当本机对象的引用计数为 1 时,我们不会阻止托管实例进行垃圾收集。 一旦引用计数增加到 1 以上,我们就会阻止托管实例被垃圾回收。

这是因为托管对象可能包含用户状态。对于镜像对应本机对象的托管对象(例如托管 UIView 实例),MonoTouch 知道该实例不能包含任何状态,因此只要没有托管代码引用托管实例,GC 就可以收集它。如果稍后需要托管实例,我们只需创建一个新实例。

所以如果我创建一个继承UIButtonCustomButton,将其作为子视图添加到我的View,让托管引用滑出范围然后运行GC,这个托管 @ 987654325@仍不符合领取条件。

为什么不能收藏?当然,它可能具有类似属性的托管状态,但是如果托管对象没有链接到它,那么谁在乎这个状态?还不如直接消失,为什么不能呢?

我在想一个可能的原因:订阅CustomButton 事件不会让 GC 保持活动状态,因此当对象被收集时,事件会停止触发。这可能会导致意外行为。

这是正确的吗?即使没有人链接它,是否还有其他原因可以使托管对象保持活动状态?

【问题讨论】:

    标签: xamarin.ios garbage-collection


    【解决方案1】:

    为什么不能收藏?当然,它可能具有类似属性的托管状态,但是如果托管对象没有与它的链接,那么谁在乎这个状态呢?还不如直接消失,为什么不能呢?

    本机代码可能对对象有引用,这可能会导致对象稍后再次出现在托管代码中。

    我相信一个代码示例可以说明会发生什么:

    class MyView : UIView {
        public string ImportantSecret;
    }
    
    class AppDelegate : UIApplicationDelegate {
        UIViewController vc;
        public override bool FinishedLaunching (UIApplication app, 
                                                NSDictionary options)
        {
            var myView = new MyView ();
            myView.ImportantSecret = "MonoTouchRocks";
    
            vc = new UIViewController ();
            vc.View = new UIView ();
            vc.View.AddSubView (myView);
    
            // When this method returns the only place where myView is referenced
            // is from inside the *native* Subviews collection.
    
            BeginInvokeOnMainThread (() =>
            {
                Console.WriteLine (((MyView) vc.Subviews [0]).ImportantSecret);
                // If the MyView instance was garbage collected and recreated
                // automatically at this point, ImportantSecret would be null.
            });
        }
    }
    

    重要:这段代码只是为了说明GC无法收集可能有状态的托管对象的原因。这个特定示例实际上不会忘记重要的秘密,因为 Subviews 数组会自动缓存在托管代码中 - 但通常情况并非如此。

    【讨论】:

    • 我终于明白了!您在这里的支持是不可或缺的。
    • 我喜欢你的两个问题和 Rolf 的精彩回答 - 刚刚学到了一些新东西 :-)
    • 我一直在玩这个。如果 myView 变量是在 using 块中创建的呢?仪器工具指示实例已被释放。感觉很别扭,但我无法识别代码的行为和问题。想法? @rolf
    猜你喜欢
    • 1970-01-01
    • 2017-06-16
    • 2011-05-12
    • 1970-01-01
    • 2020-01-10
    • 2014-12-17
    • 2021-12-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多