2013-04-26 70 views
2

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

当按钮被按下:

如果(childBroswer!= 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); 
    } 

我错过了什么?

谢谢!

回答

3

内存为本地当您拨打Dispose时不会收回对象。调用Dispose仅删除管理的引用 - 但ObjC运行时(引用计数)不会释放该对象,直到不存在本地引用。看到这个Q&A了解更多详情...

这意味着代码,如:

this.Add(webBrowser); 

会创建这样一个本地参考,并有可能(即,如果没有其它地方移除),以保持webBrowser实例活着只要this还活着。如果你保持Add ing,那么你的内存使用量将会持续增长。

+1

谢谢。 这不应该释放它吗? DismissViewController(true,delegate {0}} {} closeBrowser.TouchUpInside - = handleClose; this.Dispose(); }); – 2013-04-26 16:01:16

+0

不看不到整个来源。 'this.Dispose'将(再次)只将管理引用放到'this',所以如果其他(native)引用了this,那么它将保持活动状态(并且保持你的UIWebView也是活着的)。 – poupou 2013-04-26 17:07:42

+1

我已编辑该问题以包含子浏览器类。 希望它可以帮助,因为这导致我的应用程序很多问题... 10X! – 2013-04-26 17:14:53

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();