Grid is crashing app - by second call (MonoTouch)


#1

Calling at UIVIewController - created with New both times - the Grid dumps the App. The SampleGrid class in the sample below is creating the error. Using the ShinobiGrid class direct is working!

See error massage below:

public override void ViewDidLoad ()

{

base.ViewDidLoad ();

// THIS IS WORKING 

//ShinobiGrid m_cGrid = new ShinobiGrid( new RectangleF(10, 10, View.Bounds.Size.Width-20, View.Bounds.Size.Height-20) );

//THIS IS NOT

SampleGrid m_cGrid = new SampleGrid( new RectangleF(10, 10, View.Bounds.Size.Width-20, View.Bounds.Size.Height-20) );

m_cGrid.DataSource = new SimpleGridDataSource( );

this.View.AddSubview(m_cGrid);

}

public class SampleGrid : ShinobiGrid

{

public SampleGrid ( RectangleF frame ) : base (frame)

{

}

public void ConfigureStyles()

{

AutoresizingMask = ~UIViewAutoresizing.None;

}

}

[ERROR] FATAL UNHANDLED EXCEPTION: System.Exception: Selector invoked from objective-c on a managed object of type VISPortable.SampleGrid (0x15A1E600) that has been GC’ed —> System.MissingMethodException: No constructor found for VISPortable.SampleGrid::.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) [0x000f1] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System/Activator.cs:280 

  at System.Activator.CreateInstance (System.Type type, System.Object[] args, System.Object[] activationAttributes) [0x00000] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System/Activator.cs:234 

  at System.Activator.CreateInstance (System.Type type, System.Object[] args) [0x00000] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System/Activator.cs:229 

  at MonoTouch.ObjCRuntime.Runtime.ConstructNSObject (IntPtr ptr, IntPtr klass) [0x0000d] in /Developer/MonoTouch/Source/monotouch/src/ObjCRuntime/Runtime.cs:231 

  — End of inner exception stack trace —

  at MonoTouch.ObjCRuntime.Runtime.ConstructNSObject (IntPtr ptr, IntPtr klass) [0x00045] in /Developer/MonoTouch/Source/monotouch/src/ObjCRuntime/Runtime.cs:236 

  at MonoTouch.ObjCRuntime.Runtime.GetNSObject (IntPtr ptr) [0x0001f] in /Developer/MonoTouch/Source/monotouch/src/ObjCRuntime/Runtime.cs:280 

  at MonoTouch.ObjCRuntime.Runtime.GetNSObjectWrapped (IntPtr ptr) [0x00000] in /Developer/MonoTouch/Source/monotouch/src/ObjCRuntime/Runtime.cs:297 

  at (wrapper native-to-managed) MonoTouch.ObjCRuntime.Runtime:GetNSObjectWrapped (intptr)

  at (wrapper managed-to-native) MonoTouch.Foundation.NSObject:monotouch_release_managed_ref (intptr)

  at MonoTouch.Foundation.NSObject.ReleaseManagedRef () [0x0000b] in /Developer/MonoTouch/Source/monotouch/src/Foundation/NSObject.cs:195 

  at MonoTouch.Foundation.NSObject.FinishDispose () [0x00000] in /Developer/MonoTouch/Source/monotouch/src/Foundation/NSObject.cs:199 

  at MonoTouch.Foundation.NSObject+MonoTouch_Disposer.Drain (MonoTouch.Foundation.NSObject ctx) [0x00062] in /Developer/MonoTouch/Source/monotouch/src/Foundation/NSObject.cs:423 

  at (wrapper managed-to-native) MonoTouch.UIKit.UIApplication:UIApplicationMain (int,string[],intptr,intptr)

  at MonoTouch.UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x0004c] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:38 

  at VISPortable.Application.Main (System.String[] args) [0x00000] in /Users/kv/Documents/XCode/VISPortable/VISPortable/Main.cs:17 


#2

This is a classic MonoTouch gotcha, not a Grids thing as such, and there are many similar non-Shinobi questions on StackOverflow. Your grid is a local variable and goes out of scope when you leave ViewDidLoad. It then gets garbage collected on the managed side but is still alive on the native side. When the native object is referenced, MonoTouch can’t fiind your original object so it uses Activator.CreateInstance to try to instantiate your class using the (IntPtr) constructor, which you don’t have (but the ShinobiGrid does), hence the blowup. 

Solution: Make m_cGrid an instance variable of your viewcontroller class, like the code samples do. :wink:


#3

We have already used your solution (sorry I did not tell that) making the m_cGrid an instance of the viewcontroller does not solve the problem - the system still crash - by second call.

Other solutions?


#4

Hi TheCalvin,

I’m not sure what you mean by ‘second call’ here, could you clarify please? And is the the SimpleGrid demo app you’re modifying? I see you have

m_cGrid.DataSource = new SimpleGridDataSource( );

in your code. 


#5

Yes we used your SimpleGrid sample as template (a very simple test) - included in a navigation control, when calling the controller with the chart from the main controller everything is working perfect. Going back to the main controller and call the chart controller again the system crashes.


#6

Hi,

I’d guess (having seen this kind of bug several times) that you’re creating new grids each time you navigate around with the navigation control, but not retaining the managed side object that corresponds to each one. If native code references these (it almost certainly will) you’ll get the same problem I described above. You may also be falling foul of the caching of cells in your datasource. The datasource implementation in the sample code keeps managed-side cell objects alive by holding then in a collection, but if you’re sharing a datasource between grids with different lifetimes you may need to clear that collection when you switch grids. In short, the key is likely to be carefully matching native and managed object lifetimes. This area is one of the more troublesome in using MonoTouch  

Regards,

Robin Sillem

Lead Developer

ShinobiControls


#7

Hi,

I’d guess (having seen this kind of bug several times) that you’re creating new grids each time you navigate around with the navigation control, but not retaining the managed side object that corresponds to each one. If native code references these (it almost certainly will) you’ll get the same problem I described above. You may also be falling foul of the caching of cells in your datasource. The datasource implementation in the sample code keeps managed-side cell objects alive by holding then in a collection, but if you’re sharing a datasource between grids with different lifetimes you may need to clear that collection when you switch grids. In short, the key is likely to be carefully matching native and managed object lifetimes. This area is one of the more troublesome in using MonoTouch  

Regards,

Robin Sillem

Lead Developer

ShinobiControls


#8

Hi,

I’d guess (having seen this kind of bug several times) that you’re creating new grids each time you navigate around with the navigation control, but not retaining the managed side object that corresponds to each one. If native code references these (it almost certainly will) you’ll get the same problem I described above. You may also be falling foul of the caching of cells in your datasource. The datasource implementation in the sample code keeps managed-side cell objects alive by holding then in a collection, but if you’re sharing a datasource between grids with different lifetimes you may need to clear that collection when you switch grids. In short, the key is likely to be carefully matching native and managed object lifetimes. This area is one of the more troublesome in using MonoTouch  

Regards,

Robin Sillem

Lead Developer

ShinobiControls


#9

Hi,

It is not the implementation of the datasource that makes the trouble - in our test we did only show the RowIndex and ColumnIndex of the cell, we did not use the Collection sample - to avoid the lifetime problem. Like told before everything is working perfect aslong we do not make a implementation of the ShinobiGrid class. This Simple Class Implementation dumps the application.

public class SampleGrid : ShinobiGrid

{

public SampleGrid ( RectangleF frame ) : base (frame)

{

}

public void ConfigureStyles()

{

AutoresizingMask = ~UIViewAutoresizing.None;

}

}

As long we do not use the implementation everything is working perfect. Have you tried it with monotouch? It seams you is give the same explenation for the errors in the Grid and in the Chart even though we have avoided lifetimes problems in our internal small test samples!