We have an app in the appstore that works without any issues on iPhone 4g/4gs but when I tested it on an iPod I got a surprise because it crashes all the time at “random” places. Looking at the strack traces it seems my viewcontrollers have been GC’ed.
Will the viewcontroller be garbagecollected if I write methods like this:
public void PushShowTeamController (Object a)
{
var teamController = new TeamController (a);
NavigationController.PushViewController (teamController, true);
}
Because the iPod suddently throws an error like this:
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 ---
This will happen when an managed object is disposed (when no reference is left to an instance) and the object is later resurfaced by native code.
You need to ensure that a reference to
MyApp.TeamControlleris kept in managed code as long as it can be required (e.g. accessed) by native code.In most case MonoTouch will ensure a reference is kept. Your code:
is correct and
UINavigationControllerwill keep a reference to yourteamController. However if you callPushViewControlleron another controller then the first reference will be overwritten and will be collectable by the garbage collector (GC). This situation would lead to the exception you are seeing.Note: because you can’t predict when the GC will collect unreferenced object instance the exception will appear to be thrown randomly.