An error in unmanaged code...

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

An error in unmanaged code...

Peter Morris

I have the following code which displays the first page of a PDF.  It seems though that there is some detail missing, because as the controller is popped off the stack I get a fatal error in unmanaged code (pasted below the source).

Does anyone have a MonoTouch example of paging through a PDF?  This is how I add the controller to the stack, it seems to be fine the first time I show a PDF, but the 2nd time I try to display ANY PDF (or sometimes 3rd,4th,5th,10th) time I get an error about unmanaged code.  Here is the code I use to show the controller.

var url = NSUrl.FromFilename(fileName);
var pdfViewController = new PdfViewController(url);
NavigationController.PushViewController(pdfViewController, true);


The source code is here: http://monobin.com/__facaebee
The error info is here: http://monobin.com/__f3d617967

Regards

Pete


_______________________________________________
MonoTouch mailing list
[hidden email]
http://lists.ximian.com/mailman/listinfo/monotouch
Reply | Threaded
Open this post in threaded view
|

Re: An error in unmanaged code...

David Moles
I haven't used PDFs in iOS at all, but when I've gotten errors like this with (frex) UIImagePickerController, it's usually because something's getting prematurely garbage collected on the iOS side. It looks like you're doing a pretty good job of keeping handles to all that stuff, though, so I don't see an obvious fix. Maybe BackButtonClick() should be popping the view controller before disposing everything?

On Wed, Apr 6, 2011 at 1:13 PM, Peter Morris <[hidden email]> wrote:

I have the following code which displays the first page of a PDF.  It seems though that there is some detail missing, because as the controller is popped off the stack I get a fatal error in unmanaged code (pasted below the source).

Does anyone have a MonoTouch example of paging through a PDF?  This is how I add the controller to the stack, it seems to be fine the first time I show a PDF, but the 2nd time I try to display ANY PDF (or sometimes 3rd,4th,5th,10th) time I get an error about unmanaged code.  Here is the code I use to show the controller.

var url = NSUrl.FromFilename(fileName);
var pdfViewController = new PdfViewController(url);
NavigationController.PushViewController(pdfViewController, true);


The source code is here: http://monobin.com/__facaebee
The error info is here: http://monobin.com/__f3d617967

Regards

Pete


_______________________________________________
MonoTouch mailing list
[hidden email]
http://lists.ximian.com/mailman/listinfo/monotouch




--
David Moles

_______________________________________________
MonoTouch mailing list
[hidden email]
http://lists.ximian.com/mailman/listinfo/monotouch
Reply | Threaded
Open this post in threaded view
|

Re: An error in unmanaged code...

David Moles
Or maybe the disposing should be done in ViewDidDisappear()?

On Wed, Apr 6, 2011 at 1:28 PM, David Moles <[hidden email]> wrote:
I haven't used PDFs in iOS at all, but when I've gotten errors like this with (frex) UIImagePickerController, it's usually because something's getting prematurely garbage collected on the iOS side. It looks like you're doing a pretty good job of keeping handles to all that stuff, though, so I don't see an obvious fix. Maybe BackButtonClick() should be popping the view controller before disposing everything?

On Wed, Apr 6, 2011 at 1:13 PM, Peter Morris <[hidden email]> wrote:

I have the following code which displays the first page of a PDF.  It seems though that there is some detail missing, because as the controller is popped off the stack I get a fatal error in unmanaged code (pasted below the source).

Does anyone have a MonoTouch example of paging through a PDF?  This is how I add the controller to the stack, it seems to be fine the first time I show a PDF, but the 2nd time I try to display ANY PDF (or sometimes 3rd,4th,5th,10th) time I get an error about unmanaged code.  Here is the code I use to show the controller.

var url = NSUrl.FromFilename(fileName);
var pdfViewController = new PdfViewController(url);
NavigationController.PushViewController(pdfViewController, true);


The source code is here: http://monobin.com/__facaebee
The error info is here: http://monobin.com/__f3d617967

Regards

Pete


_______________________________________________
MonoTouch mailing list
[hidden email]
http://lists.ximian.com/mailman/listinfo/monotouch




--
David Moles



--
David Moles

_______________________________________________
MonoTouch mailing list
[hidden email]
http://lists.ximian.com/mailman/listinfo/monotouch
Reply | Threaded
Open this post in threaded view
|

Re: An error in unmanaged code...

David Moles
In reply to this post by David Moles
ViewDidDisappear should get called if you're successfully removed from the nav controller, but I guess it's not getting that far?

I'd try making the CATiledLayer and UIScrollView both fields instead of local variables. If that doesn't work, I'm probably wrong about premature garbage collection being the issue.

On Wed, Apr 6, 2011 at 1:57 PM, Peter Morris <[hidden email]> wrote:
ViewDidDisappear does not get executed so I cannot do it there.

As for popping the controller and then disposing in the button click

       void BackButtonClick(object sender, EventArgs e)
       {
           NavigationController.PopViewControllerAnimated(false);
           var page = PdfPage;
           var document = PdfDocument;
           var contentView = ContentView;

           PdfPage = null;
           PdfDocument = null;
           ContentView = null;

           page.Dispose ();
           document.Dispose ();
           contentView.Dispose ();
       }

As soon as I click the "Done" button the app instantly hangs, it doesn't even make it to a breakline on the first line of the method.  If I then click STOP in the IDE and re-run my app I get the following:
Mono.Debugger.Soft.VMDisconnectedException: Exception of type 'Mono.Debugger.Soft.VMDisconnectedException' was thrown.
 at Mono.Debugger.Soft.Connection.SendReceive (CommandSet command_set, Int32 command, Mono.Debugger.Soft.PacketWriter packet) [0x00000] in <filename unknown>:0
 at Mono.Debugger.Soft.Connection.VM_Exit (Int32 exitCode) [0x00000] in <filename unknown>:0
 at Mono.Debugger.Soft.VirtualMachine.Exit (Int32 exitCode) [0x00000] in <filename unknown>:0
 at Mono.Debugging.Soft.SoftDebuggerSession.OnExit () [0x00000] in <filename unknown>:0
 at MonoDevelop.Debugger.Soft.IPhone.IPhoneDebuggerSession.OnExit () [0x00000] in <filename unknown>:0
 at Mono.Debugging.Client.DebuggerSession.<Exit>m__B () [0x00000] in <filename unknown>:0


Whereas if I comment out the following line everything works great - except that the PDF does not appear:
           View.AddSubview(scrollView);


I really have no clue what is going on here.




--
David Moles

_______________________________________________
MonoTouch mailing list
[hidden email]
http://lists.ximian.com/mailman/listinfo/monotouch
Reply | Threaded
Open this post in threaded view
|

Re: An error in unmanaged code...

Peter Morris
The ViewDidDisappear method was not executing if I had the following
line of code in my app

     View.AddSubview(scrollView);


I upgraded to the latest version of Mono + MonoTouch 4 and now it does
get executed.  So I held some global references to the objects I created
and destroyed them in a specific way and now it seems to be working.

Code is below.....


Pete



     public class PdfViewController : UIViewController
     {
          NSUrl Url;
         UIView ContentView;
         CGPDFDocument PdfDocument;
         CGPDFPage PdfPage;
         UIScrollView ScrollView;
         CATiledLayer TiledLayer;

         public PdfViewController(NSUrl url)
             : base()
         {
             this.Url = url;
         }

         public override void ViewDidAppear(bool animated)
         {
             base.ViewDidAppear(animated);

             View = new UIView ();
             View.AutoresizingMask =
                 UIViewAutoresizing.FlexibleWidth
                 | UIViewAutoresizing.FlexibleHeight
                 | UIViewAutoresizing.FlexibleTopMargin
                 | UIViewAutoresizing.FlexibleBottomMargin
                 | UIViewAutoresizing.FlexibleLeftMargin
                 | UIViewAutoresizing.FlexibleRightMargin;
             View.AutosizesSubviews = true;

             PdfDocument = CGPDFDocument.FromUrl(Url.ToString());

             // For demo purposes, show first page only.
             PdfPage = PdfDocument.GetPage(1);
             RectangleF pdfPageRect = PdfPage.GetBoxRect(CGPDFBox.Crop);

             // Setup tiled layer.
             TiledLayer = new CATiledLayer();
             TiledLayer.Delegate = new TiledLayerDelegate(this);
             TiledLayer.TileSize = new SizeF(1024f, 1024f);
             TiledLayer.LevelsOfDetail = 5;
             TiledLayer.LevelsOfDetailBias = 5;
             TiledLayer.Frame = pdfPageRect;

             ContentView = new UIView(pdfPageRect);
             ContentView.Layer.AddSublayer(TiledLayer);

             // Prepare scroll view.
             ScrollView = new UIScrollView(View.Frame);
             ScrollView.AutoresizingMask = View.AutoresizingMask;
             ScrollView.Delegate = new ScrollViewDelegate(this);
             ScrollView.ContentSize = pdfPageRect.Size;
             ScrollView.MaximumZoomScale = 1000f;
             ScrollView.MinimumZoomScale = 0.1f;
             ScrollView.AddSubview(ContentView);
             View.AddSubview(ScrollView);
         }


         public override void ViewDidDisappear(bool animated)
         {
             base.ViewDidDisappear (animated);
             var page = PdfPage;
             var document = PdfDocument;
             var contentView = ContentView;
             var tiledLayer = TiledLayer;
             var scrollView = ScrollView;

             PdfPage = null;
             PdfDocument = null;
             ContentView = null;
             TiledLayer = null;
             ScrollView = null;

             scrollView.RemoveFromSuperview ();
             tiledLayer.RemoveFromSuperLayer ();
             page.Dispose ();
             document.Dispose ();
             contentView.Dispose ();
             scrollView.Dispose ();
             tiledLayer.Dispose ();
         }

         public class TiledLayerDelegate : CALayerDelegate
         {
             PdfViewController ParentController;

             public TiledLayerDelegate(PdfViewController parentController)
                 : base()
             {
                 ParentController = parentController;
             }

             public override void DrawLayer(CALayer layer, CGContext
context)
             {
                 if (ParentController.PdfPage == null)
                     return;
                 context.SaveState();
                 context.SetRGBFillColor( 1.0f, 1.0f, 1.0f, 1.0f);
                 context.FillRect( context.GetClipBoundingBox());
                 context.TranslateCTM( 0.0f, layer.Bounds.Size.Height);
                 context.ScaleCTM( 1.0f, -1.0f);
                 
context.ConcatCTM(ParentController.PdfPage.GetDrawingTransform(CGPDFBox.Crop,
layer.Bounds, 0, true));
                 context.DrawPDFPage(ParentController.PdfPage);
                 context.RestoreState();
             }
         }

         public class ScrollViewDelegate : UIScrollViewDelegate
         {
             PdfViewController ParentController;

             public ScrollViewDelegate(PdfViewController parentController)
                 : base()
             {
                 ParentController = parentController;
             }


             public override UIView
ViewForZoomingInScrollView(UIScrollView scrollView)
             {
                 return ParentController.ContentView;
             }
         }
     }

_______________________________________________
MonoTouch mailing list
[hidden email]
http://lists.ximian.com/mailman/listinfo/monotouch