NSAutoReleasePool и асинхронные функции - PullRequest
1 голос
/ 12 мая 2011

В моей программе есть функция, которая создает новые виджеты для представления данных, однако всякий раз, когда виджет создается, я получаю много сообщений об ошибке «AutoRelease без NSAutoReleasePool на месте».Так как NSAutoReleasePool должен автоматически создаваться в главном потоке, у меня есть предположение, что эти сообщения об ошибках появляются, потому что асинхронная функция может создавать мои потоки ...

Эта функция вызывается для создания виджетов, представляющих последниеИнформация.Эта функция вызывается довольно часто:

    private void CreateAndDisplayTvShowWidget (TvShow show)
    {
        var Widget = new TvShowWidgetController (show);
        Widget.OnRemoveWidget += ConfirmRemoveTvShow;

        Widget.View.SetFrameOrigin (new PointF (0, -150));
        Widget.View.SetFrameSize (new SizeF (ContentView.Frame.Width, 150));

        ContentView.AddSubview (Widget.View);
        show.ShowWidget = Widget;
    }

Эта функция обычно вызывается, когда эта асинхронная функция возвращает:

    private static void WebRequestCallback (IAsyncResult result)
    {
        HttpWebRequest request = (HttpWebRequest)result.AsyncState;
        HttpWebResponse response = (HttpWebResponse)request.EndGetResponse (result);

        StreamReader responseStream = new StreamReader (response.GetResponseStream ());
        string responseString = responseStream.ReadToEnd ();
        responseStream.Close ();

        ProcessResponse (responseString, request);
    }

ProcessResponse (responseString, request) выглядит так:

    private static void ProcessResponse (string responseString, HttpWebRequest request)
    {
        string requestUrl = request.Address.ToString ();

        if (requestUrl.Contains (ShowSearchTag)) {
            List<TvShow> searchResults = TvDbParser.ParseTvShowSearchResults (responseString);
            TvShowSearchTimeoutClock.Enabled = false;
            OnTvShowSearchComplete (searchResults);
        } else if (requestUrl.Contains (MirrorListTag)) {
            MirrorList = TvDbParser.ParseMirrorList (responseString);
            SendRequestsOnHold ();
        } else if (requestUrl.Contains (TvShowBaseTag)) {
            TvShowBase showBase = TvDbParser.ParseTvShowBase (responseString);
            OnTvShowBaseRecieved (showBase);
        } else if (requestUrl.Contains (ImagePathReqTag)) {
            string showID = GetShowIDFromImagePathRequest (requestUrl);
            TvShowImagePath imagePath = TvDbParser.ParseTvShowImagePath (showID, responseString);
            OnTvShowImagePathRecieved (imagePath);
        }
    }

CreateAndDisplayTvShowWidget (TvShow show) вызывается при вызове события OnTvShowBaseRectained (TvShow), когда я получаю тонны сообщений об ошибках, касающихся NSAutoReleasePool ...

Последние две функции являются частью того, чтопредполагается, что это кроссплатформенная сборка, поэтому у меня не может быть никакого кода, специфичного для MonoMac ...

Я никогда не называю никакого кода автоматического выпуска или выпуска для своих виджетов, поэтому я предполагаю, чтоПривязки MonoMac делают это автоматически как часть своей сборки мусора?

Ответы [ 3 ]

0 голосов
/ 18 мая 2011

NSAutoreleasePool нужен только при использовании функций автоматического освобождения объектов.Решение состоит в том, чтобы создать NSAutoreleasePool вокруг кода, который управляет автоматически выпущенными объектами (в асинхронном обратном вызове).

Редактировать:

Вы пытались инкапсулировать созданиекод с NSAutoreleasePool?Поскольку это единственное место, где вы вызываете код MonoMac, это должно решить эту проблему.

private void CreateAndDisplayTvShowWidget (TvShow show)
{
    using(NSAutoreleasePool pool = new NSAutoreleasePool())
    {
        var Widget = new TvShowWidgetController (show);
        Widget.OnRemoveWidget += ConfirmRemoveTvShow;

        Widget.View.SetFrameOrigin (new PointF (0, -150));
        Widget.View.SetFrameSize (new SizeF (ContentView.Frame.Width, 150));

        ContentView.AddSubview (Widget.View);
        show.ShowWidget = Widget;
    }
}

Обратите внимание, что даже если вы не используете автоматически выпущенные объекты напрямую, в некоторых случаях Cococa APIиспользуйте их под капюшоном.

0 голосов
/ 09 июля 2013

У меня была похожая проблема, и это был ответ. GetResponseStream был проблемой.Я окружил этот код ...

using (NSAutoreleasePool pool = new NSAutoreleasePool()) {
}

... и это решило мою проблему.

0 голосов
/ 15 мая 2011

Вы можете создавать пулы автоматического выпуска в точке в стеке вызовов, вы можете даже иметь несколько вложенных пулов автоматического выпуска с одним и тем же стеком вызовов. Таким образом, вы должны иметь возможность создавать пулы автоматического выпуска в функциях асинхронной записи.

...