为什么 MonoTouch GC 不能杀死引用计数 > 的托管对象?1? [英] Why can't MonoTouch GC kill managed objects with refcount > 1?

查看:14
本文介绍了为什么 MonoTouch GC 不能杀死引用计数 > 的托管对象?1?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想我已经接近理解Mono GC 和 ObjC ref 计数如何同时存在.

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

The way it works is that when a native object has a reference count of 1, we do not prevent the managed instance from getting garbage collected. As soon as the reference count increases above 1, we prevent the managed instance from getting garbage collected.

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

This is because a managed object may contain user state. For managed objects which are mirroring a corresponding native object (such as the managed UIView instance) MonoTouch knows that the instance can not contain any state, so as soon as no managed code has a reference to the managed instance, the GC can collect it. If a managed instance is required at a later stage, we just create a new one.

因此,如果我创建一个继承 UIButtonCustomButton,将其作为子视图添加到我的 View,让托管引用滑出范围然后运行GC,这个托管 CustomButton 仍然不符合收集条件.

So if I create a CustomButton that inherits UIButton, add it as subview to my View, let the managed reference slip out of scope and then run GC, this managed CustomButton still won't be eligible for collection.

为什么收不到?当然,它可能有像属性一样的托管状态,但是如果没有从托管对象到它的链接,谁在乎这个状态?也可以直接消失,为什么不能?

Why can't it be collected? Of course it may have managed state like properties, but if there is no link to it from managed objects, who cares about this state? It may as well just disappear, why can't it?

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

I'm thinking of one possible reason: subscribing to CustomButton events won't keep it alive for the GC so when the object gets collected, events stop firing. This would perhaps result in unexpected behavior.

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

Is this correct? Are there other reasons for keeping the managed object alive even if no one links it?

推荐答案

为什么收不到?当然,它可能有像属性一样的托管状态,但是如果没有从托管对象到它的链接,谁会关心这个状态呢?也可以直接消失,为什么不能?

Why can't it be collected? Of course it may have managed state like properties, but if there is no link to it from managed objects, who cares about this state? It may as well just disappear, why can't it?

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

Native code might have references to the object, which may cause the object to resurface to managed code again later.

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

I believe a code sample would illustrate what would happen:

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 数组会自动缓存在托管代码中 - 但通常情况并非如此.

Important: this code is just to illustrate the reason why the GC can't collect managed objects which may have state. This particular sample would actually not forget the important secret, since the Subviews array is automatically cached in managed code - but this is not generally true.

这篇关于为什么 MonoTouch GC 不能杀死引用计数 > 的托管对象?1?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆