2011-11-29 40 views
2

單觸式5.0.2。爲什麼在這個簡單的Monotouch代碼中看到「__NSCFString類的對象自動釋放,沒有就位」?

運行簡單的代碼下面我得到這個輸出面板:

objc[20283]: Object 0x9c08110 of class __NSCFString autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug 
objc[20283]: Object 0x9c07840 of class __NSCFData autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug 

哪些NSString的都在這裏,爲什麼漏水?這似乎足以創建一個新的Uri()和一個新的WebClient()objetc。事件處理程序甚至不需要連接。

using System; 
using MonoTouch.Foundation; 
using MonoTouch.UIKit; 
using System.Net; 
using System.IO; 

namespace DownloadTest 
{ 
    [Register ("AppDelegate")] 
    public partial class AppDelegate : UIApplicationDelegate 
    { 
     UIWindow window; 

     public override bool FinishedLaunching (UIApplication app, NSDictionary options) 
     { 
      window = new UIWindow (UIScreen.MainScreen.Bounds); 

      UIButton btn = UIButton.FromType (UIButtonType.RoundedRect); 
      btn.Frame = new System.Drawing.RectangleF (40, 40, 100, 30); 
      btn.TouchUpInside += delegate { 
       // These two lines seem to caus the leak. 
       Uri uri = new Uri ("http://silverlightinaction.com/video3.wmv"); 
       WebClient webClient = new WebClient(); 
       // This line does not matter, the info about the leaking NSString alsp appears without an event being attached. 
       webClient.OpenReadAsync (uri);        
      }; 
      window.AddSubview (btn); 

      window.MakeKeyAndVisible(); 

      return true; 
     } 

     void HandleWebClientOpenReadCompleted (object sender, OpenReadCompletedEventArgs e) 
     { 
      using (var pool = new NSAutoreleasePool()) 
      { 
       using (Stream stream = e.Result) 
       using (FileStream fileStream = File.OpenWrite(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "download.bin"))) 
       { 
        stream.CopyTo (fileStream, 30000); 
        stream.Close(); 
        fileStream.Close(); 
       } 
      } 
     } 
    } 
} 
+0

這看起來像http://bugzilla.xamarin.com/show_bug.cgi?id=1999重複,但我們並沒有一個完整的測試用例來複制它(你的工作完美:-)。我將把它與這個問題聯繫起來並追蹤下來。謝謝 – poupou

+0

有人對我的痛苦感到高興!大!請給我免費的聖誕節蛋糕! :-) – Krumelur

回答

2

這是一個MonoTouch錯誤。 WebClient使用Thread它不自動地圍繞正在執行的代碼創建一個NSAutoreleasePool(例如,像您在委託中那樣)。這可能會導致一些泄漏 - 就像你看到警告信息一樣。

請注意,使用(線程)ThreadPool已經確保NSAutoreleasePool覆蓋線程的執行。

+0

該錯誤是否得到解決?或者我必須使用線程池? – Krumelur

+0

它將被固定,單向('WebClient')或另一個('Thread',我的首選項),因爲這無法在用戶代碼中修復(至少不是使用'HttpWebRequest'而不是'WebClient') – poupou

1

我創建了一個派生自WebClient的新類,並覆蓋了「OnDownloadedCompleted」並在使用塊中創建了自己的池。這似乎擺脫了調試信息,不知道它是否是完美的修復。

using(var a = new MonoTouch.Foundation.NSAutoreleasePool()) 
{ 
    base.OnDownloadDataCompleted (args); 
} 
相關問題