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.TeamController is 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:
NavigationController.PushViewController (teamController, true);
is correct and UINavigationController will keep a reference to your teamController. However if you call PushViewController on 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.
From my experience this happens when i use a lot of dispose() on managed objects instead of setting them to null and leaving the GC to do its job. Also anonymous delegates combined with dispose() can lead to such problems
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With