Почему я вижу «Объект класса __NSCFString, автоматически выпущенный без пула на месте» в этом простом коде Monotouch? - PullRequest
2 голосов
/ 29 ноября 2011

Monotouch 5.0.2.

Запустив простой код ниже, я получаю это на панели вывода:

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

Какие строки NSS просачиваются сюда и почему? Кажется, этого достаточно, чтобы просто создать новый 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 ();
                }
            }
        }
    }
}

Ответы [ 2 ]

2 голосов
/ 29 ноября 2011

Это ошибка MonoTouch.WebClient использует Thread, который не автоматически создает NSAutoreleasePool вокруг исполняемого кода (например, как вы сделали в своем делегате).Это может вызвать некоторые утечки - точно так же, как вы видите с предупреждающими сообщениями.

Обратите внимание, что использование (threads from) ThreadPool уже гарантирует, что NSAutoreleasePool охватывает выполнение потока.

1 голос
/ 05 января 2012

Я создал новый класс, производный от WebClient, и переопределил «OnDownloadedCompleted» и создал свой собственный пул в блоке using. Казалось, это избавляет от отладочных сообщений, хотя и не уверен, что это идеальное решение.

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