2011-05-12 23 views
1

データを表す新しいウィジェットを作成する関数がプログラムにありますが、ウィジェットが作成されるたびに「NSAutoReleasePoolを使用しない自動リリース」というエラーメッセージが多く表示されます。 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、要求は)次のようになります。

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)は、イベントOnTvShowBaseRecieved(TvShow)が呼び出されたときに呼び出されます。これはNSAutoReleasePoolに関するエラーメッセージを表示します。

最後の2つの関数は、クロスプラットフォームアセンブリすることになっているものの一部であるので、私はそこに任意のMonoMac固有のコードを持つことができません...

私は、任意の自動リリースを呼び出すことはありませんか私のウィジェットのリリースコードなので、MonoMacバインディングは自動的にガベージコレクションの一部としてこれを行うと仮定します。

+0

何が間違っているかを理解するのに役立つかもしれないこの質問に、他に何を追加できますか?私はまだ答えに近づくことができません... –

答えて

0

呼び出しスタック内のポイントで自動解放プールを作成することができます。同じ呼び出しスタックを持つ複数のネスト化された自動解放プールを持つこともできます。したがって、非同期エントリ関数でオートリアーゼプールを作成できるはずです。

+0

主な質問を編集しました... –

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はフードudnerそれらを使用するいくつかのケースがあることに注意してください。

+0

主な質問を編集しました... –

+0

答えを編集しました。 –

+0

まだエラーが発生しているようです。新しいウィジェットが追加される前、またはウィジェットが更新される前にエラーが表示されないので、アプリケーションが初めて起動し、保存ファイルからウィジェットを作成するだけで、 "using"ステートメント... –

0

私は同様の問題を抱えていましたが、それは問題だったresponse.GetResponseStreamでした。私はこのコードで囲んだ...

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

...私の問題を解決しました。

関連する問題