2011-11-29 9 views
2

モノタッチ5.0.2。 I以下の簡単なコードを実行この単純なモノタッチコードで、「プールされていない状態でオートレリースされたクラス__NSCFStringのオブジェクト」が表示されるのはなぜですか?

は、出力パネルにこれを取得する:NSStringsがここに漏れて、なぜされている

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 

?新しいUri()オブジェクトと新しいWebClient()オブジェクトを作成するだけで十分です。イベントハンドラはアタッチする必要はありません。

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のバグです。 WebClientThreadを使用しません。は自動的にに実行されるコードの周りにNSAutoreleasePoolを作成します(例:代理人のように)。警告メッセージが表示されているように、リークが発生する可能性があります。

(スレッドの)ThreadPoolを使用すると、すでにNSAutoreleasePoolがスレッドの実行をカバーしていることが確認されています。

+0

このバグは修正されますか?またはスレッドプールを使用する必要がありますか? – Krumelur

+0

これは(少なくともWebClientではなく 'HttpWebRequest'を使用しないで)これをユーザコードで修正することができないので、一方向(' WebClient')または別の( 'Thread'、私の好み) – poupou

1

WebClientから派生した新しいクラスを作成し、 "OnDownloadedCompleted"を上書きし、使用ブロック内に自分自身のプールを作成しました。これはデバッグメッセージを取り除くように思えましたが、それが完璧な修正であるかどうかはわかりません。

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