5

バックグラウンドで何らかの操作を行うためにスレッドを切り離しています。以下のコードを参照してください。

 currentThread = [[NSThread   alloc]initWithTarget:contactServiceselector:@selector(requestForContactBackup:)object:msisdn];

 [currentThread start];

この currentThread は、AppDelegate で宣言されたポインターです。ビューにボタンがあり、それをタップすると、バックグラウンド スレッドの実行が停止するはずです。以下のコードを参照してください。

-(void)cancelTheRunningTasks {
    
   if(self.currentThread !=nil) {

        [currentThread cancel];
        NSLog(@"IsCancelled: %d",[currentThread isCancelled]);   //here Yes returns
        [self removeNetworkIndicatorInView:backUpViewController.view];
    }  
}

以下のコードの問題は、バックグラウンド スレッドがまだ実行中のままであることです。

私の質問は、スレッド参照があり、メインスレッドからバックグラウンドスレッドをキャンセル/停止/強制終了する方法ですか?

可能な解決策を教えてください。ありがとう。

4

3 に答える 3

4

バックグラウンドスレッドは、メソッドのいずれかを使用して、キャンセルされたかどうかを確認する必要がありますisCancelled...

if ([[NSThread currentThread] isCancelled]) {
    // do cleanup here
    [NSThread exit];
}

スレッドがどのような状態にあるかを知る方法がないため、外部でスレッドを強制終了することはできません。したがって、スレッドを強制終了すると、不確定な動作が発生します(スレッドが強制終了されたときにアロケータでミューテックスを押し下げていた場合を想像してください。 ..痛い)。

于 2013-03-14T16:18:51.000 に答える
3

cancel
レシーバーのキャンセル状態を変更して、終了する必要があることを示します。

exit
現在のスレッドを終了します。

NSThread クラス リファレンスを確認する

取り消しおよび操作オブジェクトの詳細については、「NSOperation クラス リファレンス」を参照してください。

: OS X v10.6 では、キャンセル メソッドの動作は、操作が現在操作キューにあるかどうかによって異なります。キューに入れられていない操作の場合、このメソッドは操作をすぐに終了したものとしてマークし、適切な KVO 通知を生成します。キューに入れられた操作の場合、操作を実行準備完了としてマークし、キューにその start メソッドを呼び出させるだけです。これにより、その後終了し、キューから操作がクリアされます。

于 2013-03-14T16:07:07.753 に答える
3

問題を解決しました。まさに私がやりたかったことは、メインスレッドまたは他のスレッドからのバックグラウンドスレッドの動作状態を停止または強制終了したいということです。Apple のドキュメントといくつかの投稿を読んで、すべてのスレッドが共通のメモリ空間とリソースを共有し、他のスレッドによってスレッドを強制終了するのは良くないため、他のスレッドから 1 つのスレッドを強制終了することはできないと結論付けました (しかし、1 つのプロセスは強制終了できます)。 2 つのプロセス間で共通のメモリ空間が共有されないため)。次に、そのようにスレッドを終了/強制終了できないという情報を得ましたが、実行中のスレッドのキャンセル プロパティを他のスレッドから設定することはできます。(ユーザーがタスクのキャンセルを要求したコード内)。

したがって、ここで cancel プロパティを設定できます。そして、実行中のバックグラウンド タスク コード内で、cancel プロパティが設定されているかどうかを確認します。(コードのチャンク実行後に監視する必要があります)。cancel プロパティが設定されている場合/Yes の場合は、そのバックグラウンド スレッド コードで [Thread exit] を呼び出し、そのスレッドによって割り当てられたすべてのメモリを解放して、メモリ リークを保護します (自動解放プールは、ここではリソースを解放しません)。

これは私が問題を解決した方法です。

簡単に --> キャンセルしたい特定のタスクのプロパティをキャンセル セットとして設定するだけです。(キャンセルを設定するメソッドは、スレッド オブジェクト参照によって呼び出されます)。

 if(self.currentThread != nil && [currentThread isExecuting])
   {
      [currentThread cancel];
   }

次に、コードでキャンセル プロパティを監視します。プロパティが設定されている場合は、スレッドを終了します。

if([appDelegate.currentThread isCancelled])
 {
      [NSThread exit];
 }

誰かがこれよりも優れた解決策を持っている場合は、参照してください。それ以外の場合も正常に動作します。

于 2013-03-15T10:21:05.077 に答える