我有什么选择来寻找Monotouch异常,如"系统.异常:从objective-c中调用的选择器已经被GC&#



我在下面得到了一些例外。我有什么选择来追踪这些问题?我有点迷路了,因为它们只偶尔发生,只在设备上,但从来没有在模拟器上。

System.Exception: Selector invoked from objective-c on a managed object that has been GC'ed ---> System.MissingMethodException: No constructor found for Browser.FolderListController::.ctor(System.IntPtr)
  at System.Activator.CreateInstance (System.Type type, BindingFlags bindingAttr, System.Reflection.Binder binder, System.Object[] args, System.Globalization.CultureInfo culture, System.Object[] activationAttributes) [0x00000] in <filename unknown>:0
  at System.Activator.CreateInstance (System.Type type, System.Object[] args, System.Object[] activationAttributes) [0x00000] in <filename unknown>:0
  at System.Activator.CreateInstance (System.Type type, System.Object[] args) [0x00000] in <filename unknown>:0
  at MonoTouch.ObjCRuntime.Runtime.ConstructNSObject (IntPtr ptr, IntPtr klass) [0x00000] in <filename unknown>:0
  --- End of inner exception stack trace ---
  at MonoTouch.ObjCRuntime.Runtime.ConstructNSObject (IntPtr ptr, IntPtr klass) [0x00000] in <filename unknown>:0
  at MonoTouch.ObjCRuntime.Runtime.GetNSObject (IntPtr ptr) [0x00000] in <filename unknown>:0
  at MonoTouch.ObjCRuntime.Runtime.GetNSObjectWrapped (IntPtr ptr) [0x00000] in <filename unknown>:0
  at (wrapper native-to-managed) MonoTouch.ObjCRuntime.Runtime:GetNSObjectWrapped (intptr)
  at MonoTouch.UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x00000] in <filename unknown>:0
  at Browser.Application.Main (System.String[] args) [0x00000] in .../Main.cs:15

这与OP的情况并不完全相关,但是当从nib加载视图时,我得到了这个错误,结果证明我没有正确设置视图类的构造函数:

public MyView() : base()
{
    // Wrong!
}

需要包含IntPtr形参:

public MyView(IntPtr handle) : base(handle)
{
}

没有一个简单的答案,但我可以分享一个方法来帮助他们完成:

就像@Miguel说的那样,这样的异常意味着运行时试图重新呈现Browser.FolderListController的实例。这意味着一个或多个Browser.FolderListController实例正在被收集,即使它们以后仍然需要。

您的第一步应该是检查每个Browser.FolderListController实例的生命周期。例如

  • 创建目录;
  • 调用发生的地方;
  • 在那里你Dispose他们手动 -这可能与任何保留'ing MonoTouch尝试做帮助你的冲突;
  • 为空或从集合中删除(即删除引用)…

一旦你知道了生命周期,你就可以:

  • Browser.FolderListController添加终结器并在其中设置断点。终结器是在一个单独的线程中执行的,所以它不会告诉你最后一个引用是在哪里被删除的——但它会告诉你大约是在某个点之前

  • ;
  • 添加.ctor(IntPtr)构造函数并在其中添加断点。同样,它不会给你一个确切的点(需要的地方),但它会告诉你大约何时(至少不是在另一个点之前);

执行您的应用程序,获取崩溃,然后查看在这两个时间点之间发生了什么(与您的生命周期相比)

上面的意思是一个对象被创建,传递给Objective-C保存,然后被Mono垃圾收集,然后在回调或一些委托调用时重新浮出Mono。

这通常意味着在我们的代码中,我们没有捕捉到需要保持显式引用的情况。这个测试用例会很有用,因为它可以帮助我们在MonoTouch中修复这个问题。

我们还开发了一种新技术,可以一次消除所有这些问题,但代码还没有准备好公开使用。

相关内容