2011-11-29 46 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); 
} 
相关问题