views:

304

answers:

4

Hey

The following view crashes the iPhone

If I comment out the

using (webView = new UIWebView(webRect)) {
}

section - it does not.

using System;
using MonoTouch.UIKit;
using MonoTouch.Foundation;
using System.Drawing;

namespace WmcStarClient
{


    public class EventDetailView : UIViewController
    {
        public WmcStarEventService.Event _event;
        public UIWebView webView;

        public EventDetailView ()
        {
        }

        public EventDetailView (WmcStarEventService.Event eventParam)
        {
            _event = eventParam;
        }

        public override void ViewDidLoad ()
        {
            base.ViewDidLoad ();

            var webRect = new RectangleF(0f, 0f, 320f, 460f);

            using (webView = new UIWebView(webRect)) {
            }
        }
    }
}

has anyone seen this before?

w://

+2  A: 

This was a bug that was fixed in the first beta of the 1.5 series:

http://monotouch.net/Releases/MonoTouch_1.4.99

Geoff Norton
hmph... i did just upgrade to this.it doesn't actually crash imediately - it's just if i load that screen and then restart the app - it doesn't get past the splash screen. but if i comment out the uiwebview code it's ok :(
cvista
A: 

This is potentialy a different/new bug - i've gotten a better response over at the monotouch forums:

http://forums.monotouch.net/yaf_postsm1500.aspx#post1500

w://

cvista
it's actually a bug in catnap orm - using an older version of sqlite3.cs - i'm going to contact the creater and get that fixed :)
cvista
A: 

It seems very strange to me to wrap that in a using statement. It's as if your disposing something while still loading. Are you sure that's right?

Dave Van den Eynde
recomended on the examples site :)
cvista
I just looked at the example in monocatalog, and I don't see it being wrapped in a using statement. What does calling Dispose() on the UIWebView do then?
Dave Van den Eynde
http://monotouchexamples.com/#3to be fair - when i thought it was the uiwebview that was causing the issue i thought it had something to do with it not disposing correctly - this sort of backed that up - it's possible it's unecessary. :)
cvista
Okay, but in that example the webView gets added to another view as a subview before leaving the using() scope, so the ownership is transferred.
Dave Van den Eynde
The creator of that example, chrisntr, is also a user on this site. Perhaps he could shed some light on this issue?
Dave Van den Eynde
The code above is the minimal code i could get to re-create the bug :)in the app i was adding the webview to the view inside the using.turned out it was an issue with catnap orm using an old interop binding which was screwing with memory allocation - removing catnap fixed the issue - i'm going to try updatin my build of catnap to use the correct sqlite3.cs and see if it still works.
cvista
Hey cvista, I've tried re-creating the bug but having no luck. As Geoff said - it could have been a bug that has been fixed. There should be no issue wrapping the code round the UIWebView though.
chrisntr
I'm still confused about why the using() is needed.
Dave Van den Eynde
hey chrisntr - look here for the full shizam: http://forums.monotouch.net/yaf_postst487_UiWebView-crashes-iPhone.aspx :) - dave - i dont think it hurts to have it there - so no big shakes
cvista
A: 

When you're using the "using" construct, you are calling Dispose() on the webview, which is mapped to the "release" message in the Cocoa runtime.

So you are releasing the webview object, but you're still holding on to the reference in your class. The first time you try to access it, you're accessing a released instance.

Aren't you adding the webview to your view as a subview? If so, at what point?

The correct code, IMHO, would be:

    public class EventDetailView : UIViewController
    {
        public WmcStarEventService.Event _event;
        public UIWebView webView;

        public EventDetailView ()
        {
        }

        public EventDetailView (WmcStarEventService.Event eventParam)
        {
            _event = eventParam;
        }

        public override void ViewDidLoad ()
        {
            base.ViewDidLoad ();

            var webRect = new RectangleF(0f, 0f, 320f, 460f);

            webView = new UIWebView(webRect);

            View.AddSubView(webView);
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
               webView.Dispose();

            base.Dispose(disposing);
        }
    }

Note that overriding Dispose() is not required, but it should help to release memory earlier than simply relying on the garbage collector.

Philippe Leybaert