1

私はかなり標準的な設定をしています。ユーザーインタラクションを処理するUIViewControllerと、UIControllerが表示されたときに実際の作業を行うやや長時間実行されるNSThreadがあります。私が抱えていた問題の1つは、NSThreadをキャンセルしたいときです。標準のNSThreadセマンティクスは問題ありません。スレッドを終了し、それ自体をクリーンアップして(UIViewControllerへの参照を解放するように)、UIViewControllerをポップします。したがって、私のコードは次のようになります。

NSThreadセレクターの場合:

-(void) nsThreadWork
{
  // do work here
  @synchronized(self)
  {
    [nsThreadInstance release];
    nsThreadInstance = nil;
  }
}

スレッドを生成するUIViewControllerでは、次のようになります。

 -(void) startThread    
 {
   nsThreadInstance = [[NSThread alloc] initWithTarget:self 
                                        selector:@(nsThreadWork) ...];
   [nsThreadInstance start];
   [nsThreadInstance release];
 }

そしてキャンセルしたい場合:

// assume that this will be retried until we can execute this successfully.
-(void) cancelBackgroundOpAndPopViewController
{
  @synchronized(self)
  {
    if (nsThreadInstance == nil)
    { 
        [self popViewController];
    }
  }
} 

しかし、これが正しいかどうかは疑問です。問題は、UI要素はメインスレッドからのみ操作できることです。NSThreadが終了する前にViewControllerをポップすると、NSThreadが終了してView Controllerを解放します。これは、NSThreadのコンテキストから割り当てが解除され、アサートが発生することを意味します。上記のコードではすべてが正しく機能しているように見えますが、runloopがNSThreadの割り当てを解除するタイミングがわかりません。誰かが洞察を提供できますか?

4

0 に答える 0