2

在我的应用程序中使用 UIWebView,我似乎无法释放它正在使用的内存。我有一个 UIButton,它加载一个包含 UIWebView 的视图控制器。当 webView 被加载时,Real Memory(使用 Instruments 检查它)会上升,但在我尝试释放它之后并没有降低。

按下按钮时:

如果(孩子浏览器!= null)

        {
            childBroswer.Dispose();
            childBroswer = null;
        }

        childBroswer = new ChildBrowser(url);

        AppDelegate d = (AppDelegate)UIApplication.SharedApplication.Delegate;

        if ( d.rootNavigationController.RespondsToSelector(
            new MonoTouch.ObjCRuntime.Selector("presentViewController:animated:completion:")))
        {
                d.rootNavigationController.PresentViewController(childBroswer, true, null);
        }
        else
        {
            d.rootNavigationController.PresentModalViewController(childBroswer, true);
        }

子浏览器类:

 public partial class ChildBrowser : UIViewController
{
    public string _url {get;set;}
    UIActivityIndicatorView activityIndicator;
    UIWebView webBrowser;
    NSUrl nsURL;
    NSUrlRequest nsURLRequest;
    public ChildBrowser (string url) : base ("ChildBrowser", null)
    {
        nsURL = new NSUrl(url);
        nsURLRequest = new NSUrlRequest(nsURL);
    }

    public override void DidReceiveMemoryWarning ()
    {
        // Releases the view if it doesn't have a superview.
        base.DidReceiveMemoryWarning ();

        // Release any cached data, images, etc that aren't in use.
    }

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

        if (webBrowser == null)
        {
            webBrowser = new UIWebView(new RectangleF(0,41,320,380));
        }

        this.Add(webBrowser);

        webBrowser.LoadFinished += (object sender, EventArgs e) => {
            activityIndicator.StopAnimating();
        } ;

        webBrowser.LoadStarted += (object sender, EventArgs e) => {

            if (activityIndicator == null)
            {
                activityIndicator = new  UIActivityIndicatorView(new RectangleF(UIScreen.MainScreen.Bounds.Width / 2 - 50,
                                                                                UIScreen.MainScreen.Bounds.Height / 2 - 30,100,100));
                activityIndicator.Color = UIColor.Black;
            }

            activityIndicator.StartAnimating();
            this.Add(activityIndicator);
        } ;

        webBrowser.LoadHtmlString("<html><head></head><body></body></html>",null);   //stringByEvaluatingJavaScriptFromString:@"document.body.innerHTML = \"\";"];
        webBrowser.LoadRequest(nsURLRequest);

        closeBrowser.TouchUpInside +=  handleClose;


        // Perform any additional setup after loading the view, typically from a nib.
    }

    private void handleClose(object sender, EventArgs e)
    {
        webBrowser.Delegate = null;
        webBrowser.StopLoading();
        webBrowser.Dispose();

        DismissViewController(true,delegate {
            closeBrowser.TouchUpInside -=  handleClose;
            webBrowser.RemoveFromSuperview();
            this.Dispose();
        } );
    }

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


    }

    public override void ViewDidDisappear(bool animated)
    {
        base.ViewDidDisappear(true);
        //webBrowser.RemoveFromSuperview();
    }

    public void webViewDidFinishLoad(UIWebView webView)
    {
        //string u = "";
    }

    protected override void Dispose(bool disposing) 
    {
        ReleaseDesignerOutlets();
        base.Dispose(disposing);
    }

我错过了什么?

谢谢!

4

2 回答 2

3

调用时不会回收本机对象的内存Dispose。调用Dispose只会删除托管引用 - 但 ObjC 运行时(引用计数)在没有本机引用之前不会释放对象。有关更多详细信息,请参阅此问答...

这意味着代码如:

this.Add(webBrowser);

将创建这样的本机webBrowser引用,并且很可能(即,如果没有在其他地方删除)只要实例还活着,就可以保持该实例this的活动状态。如果您继续Add使用,那么您的内存使用量将不断增长。

于 2013-04-26T15:59:07.387 回答
2

我是 OP - 似乎释放 UIWebView 的内存使用量非常困难,即使在 Objective-C 中这样做也是如此。

我最终所做的并没有解决问题但改善了内存释放的方法是在关闭 UIWebView 时添加以下行:

NSUrlCache.SharedCache.RemoveAllCachedResponses();

        NSUrlCache.SharedCache.DiskCapacity = 0;

        NSUrlCache.SharedCache.MemoryCapacity = 0;

        webView.LoadHtmlString("",null);

        webView.EvaluateJavascript("var body=document.getElementsByTagName('body')[0];body.style.backgroundColor=(body.style.backgroundColor=='')?'white':'';");

        webView.EvaluateJavascript("document.open();document.close()");

        webView.StopLoading();

        webView.Delegate = null;

        webView.RemoveFromSuperview();

        webView.Dispose();
于 2013-06-07T14:42:32.863 回答