我的程序中有一个函数可以创建新的小部件来表示数据,但是每当创建一个小部件时,我都会收到很多“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);
}
}
调用事件OnTvShowBaseRecieved(TvShow)时调用 CreateAndDisplayTvShowWidget(TvShow show),这是我收到关于NSAutoReleasePool的吨错误消息...
最后两个函数是应该是跨平台程序集的一部分,所以我不能在那里有任何特定于MonoMac的代码......
我从不为我的小部件调用任何自动释放或释放代码,所以我假设MonoMac绑定会自动执行此操作作为其垃圾收集的一部分?
答案 0 :(得分:0)
您可以在调用堆栈中的点处创建自动释放池,甚至可以使用具有相同调用堆栈的多个嵌套自动释放池。因此,您应该能够在异步输入函数中创建自动释放池。
答案 1 :(得分:0)
如果使用对象的自动释放功能,则只需要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会使用它们。
答案 2 :(得分:0)
我有一个类似的问题,这是问题的响应.GetResponseStream。我用...包围了这段代码。
using (NSAutoreleasePool pool = new NSAutoreleasePool()) {
}
......这解决了我的问题。