当前位置 : 主页 > 手机开发 > ios >

xamarin.ios – 从已经过GC的托管对象上的objective-c调用的Selector,如何避免viewcontr

来源:互联网 收集:自由互联 发布时间:2021-06-11
我们在appstore中有一个应用程序在iPhone 4g / 4gs上没有任何问题,但是当我在iPod上测试时,我得到了一个惊喜,因为它在“随机”地方一直崩溃.看着strack的痕迹,我的视觉控制器似乎已经过了
我们在appstore中有一个应用程序在iPhone 4g / 4gs上没有任何问题,但是当我在iPod上测试时,我得到了一个惊喜,因为它在“随机”地方一直崩溃.看着strack的痕迹,我的视觉控制器似乎已经过了GC.

如果我写这样的方法,viewcontroller会被垃圾收集:

public void PushShowTeamController (Object a)
{
  var teamController = new TeamController (a);
  NavigationController.PushViewController (teamController, true);
}

因为iPod突然抛出这样的错误:

Jan  6 18:52:09 unknown MyApp[5197] <Warning>: Received memory warning.
 Jan  6 18:52:10 unknown UIKitApplication:mypackage.app[0x9db2][5197] <Notice>: Unhandled Exception: System.Exception: Selector invoked from objective-c on a managed object that has been GC'ed ---> System.MissingMethodException: No constructor found for MyApp.TeamController::.ctor(System.IntPtr)
 Jan  6 18:52:10 unknown UIKitApplication:mypackage.app[0x9db2][5197] <Notice>:   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 
 Jan  6 18:52:10 unknown UIKitApplication:mypackage.app[0x9db2][5197] <Notice>:   at System.Activator.CreateInstance (System.Type type, System.Object[] args, System.Object[] activationAttributes) [0x00000] in <filename unknown>:0 
 Jan  6 18:52:10 unknown UIKitApplication:mypackage.app[0x9db2][5197] <Notice>:   at System.Activator.CreateInstance (System.Type type, System.Object[] args) [0x00000] in <filename unknown>:0 
 Jan  6 18:52:10 unknown UIKitApplication:mypackage.app[0x9db2][5197] <Notice>:   at MonoTouch.ObjCRuntime.Runtime.ConstructNSObject (IntPtr ptr, IntPtr klass) [0x00000] in <filename unknown>:0 
 Jan  6 18:52:10 unknown UIKitApplication:mypackage.app[0x9db2][5197] <Notice>:   --- End of inner exception stack trace ---
当处理托管对象时(当没有对实例进行引用时),并且该对象稍后由本机代码重新表面化时,将发生这种情况.

您需要确保对托管代码中保留对MyApp.TeamController的引用,只要本机代码可以(例如访问)它.

在大多数情况下,MonoTouch将确保保留参考.你的代码:

NavigationController.PushViewController (teamController, true);

是正确的,UINavigationController将保持对teamController的引用.但是,如果在另一个控制器上调用PushViewController,则第一个引用将被覆盖,并且可由垃圾收集器(GC)收集.这种情况会导致你看到的例外情况.

注意:因为您无法预测GC何时收集未引用的对象实例,所以异常将被随机抛出.

网友评论