我何时必须保留对我的控制器或视图的引用,何时不是?见例子

时间:2011-09-15 11:24:11

标签: .net objective-c mono garbage-collection xamarin.ios

在使用Monotouch时,我一直想知道两种情况。他们处理了保留对UIViewControllerUIView

的引用的要求

示例一(我发现在MT bug数据库中)。它正在实现MKMapViewDelegate,并且从GetViewForAnnotation返回的视图将被垃圾收集,除非保留托管引用:

class MapViewDelegate : MKMapViewDelegate
{
    public override MKAnnotationView GetViewForAnnotation (MKMapView mapView, NSObject annotation)
    {
        var myAnnotation = annotation as MyAnnotation;
        var view = new MKPinAnnotationView (myAnnotation, "myannotation");
        var button = UIButton.FromType (UIButtonType.DetailDisclosure);
        view.RightCalloutAccessoryView = button;

        // I have had this fail as "invalid selector", and also a SIGSEGV crash
        button.TouchDown += delegate {
            Console.WriteLine("I was touched!");
        };

        annotationView = view;

        return annotationView;
    }
}

示例二:如果我使用PresentModalViewController()我似乎能够在没有托管引用的情况下生存:

ModalSettingsController oSettingsController = new ModalSettingsController ( );
this.PresentModalViewController(oSettingsController, true);

在这种情况下,我从未遇到过NULL引用,SIGSEGV或类似内容。 看起来在这种情况下,“某事”正在引用。

我遇到的问题是:如果我要使用纯粹的C#环境而不是ObjC世界,那么来自示例1的代码可以毫无问题地运行;视图已创建并分配给其他内容,这意味着存在引用。但是,由于第一个示例中返回的视图返回到ObjC并且没有托管引用,因此GC将清除托管版本。这让我有些困惑。我怎么能弄清楚在哪些情况下我必须保留参考,何时不参考? 我是否必须查看Apple的文档并查看收件人是否保留视图或控制器?

1 个答案:

答案 0 :(得分:1)

  

我是否必须查看Apple的文档并查看收件人是否保留视图或控制器?

没有。通常(大约98%的API)MonoTouch将处理所需的引用,以便在需要时让托管对象生效。这可以完成,因为您从应用程序中调用了一些托管(C#)代码。 E.g。

 this.PresentModalViewController(oSettingsController, true);

这允许 PresentModalViewController 托管方法在需要时为 oSettingsController 保留引用(如果需要)。

那么the issue与某些API有什么关系?问题是谁在调用API。 E.g。

public override MKAnnotationView GetViewForAnnotation (MKMapView mapView, NSObject annotation)

如果这被称为C#形式,则不会出现问题,即您的声明 C#mostly正确无误。

然而,它是从 ObjectiveC 调用的,因为我们从继承的本机类型覆盖方法。因此,在这种情况下,托管对象视图在方法返回后没有(托管)引用(除非您添加一个,如示例#1)。但是本机调用者将保留本地部分视图,这样一切都可以工作......直到您的应用程序尝试返回托管代码

自托管对等方以来,例如查看已被收集,然后其中的所有托管也将被收集(例如按钮)。这就是崩溃经常发生在事件中的原因,例如在您分配给 TouchDown 的代理中。

据说我们正在制定解决方案,以便在未来版本的MonoTouch中涵盖此案例。加入c.c.如果您希望获得有关进展的通知,请bug report