2013-04-26 47 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();