0

私のアプリでは、バックグラウンドでサーバーを実行しています。そのために a を使用しNSOperationています。(以前はGCDを使用していましたが、停止できるようにする必要があるため、に切り替えましたNSOperationが、まだ方法がわかりません。)

基本的に、私のNSOperationサブクラスは次のようになります。

- (void)main {
    server_main(var1, var2);
}

サーバーなのでserver_main基本的に機能は戻りません。また、その機能の実装を制御することもできません。

ユーザーがサーバーの設定を変更することがあります。これが発生した場合、サーバーを停止してから再起動したいと考えています。if (self.isCancelled)理解が正しければ、NSOperationサブクラスのようなことをする必要があるのですが、server_main関数内でスタックしてしまうので、実際に動作するかどうかは疑問です。

では、どうすればサーバーを停止できますか?

どうもありがとう!

4

3 に答える 3

2

適切に行うには、Concurrency Programming GuideのResponding to Cancellation Eventsを参照してください。

クラスはクライアントが操作をキャンセルする方法を提供しますがNSOperation、キャンセル イベントの認識は必然的に任意です。操作が完全に終了した場合、割り当てられたリソースを再利用する方法がない可能性があります。その結果、操作オブジェクトはキャンセル イベントをチェックし、操作の途中でイベントが発生した場合は正常に終了することが期待されます。

操作オブジェクトでキャンセルをサポートするには、オブジェクトのisCancelledメソッドをカスタム コードから定期的に呼び出し、返された場合はすぐに返すだけYESです。

server_mainこれは、次のいずれかになるように変更できるようにする必要があると私が本当に思うことを、長く曲がりくねった言い方です。

  • isCancelled定期的にチェックするか、

  • コールバック/プログレス デリゲート メソッド ブロックを提供して、それを自分で実行できるようにするだけでなく、 cancel に呼び出すことができる追加の関数/メソッドをいくつか提供しserver_mainて、重要なクリーンアップ プロセスを実行できるようにします。

プロセスの強制終了を開始した場合 (可能であれば)、間違いなくリソースをリークするかserver_main、一貫性のない状態のままにします。

これがあなたが探している答えではないことはわかっていますが、これが操作のキャンセルの仕組みです。ごめん。

于 2013-05-01T13:02:34.363 に答える
0

このコードを試すことができます:

@interface Canceller
{
    BOOL _shouldCancel;
}
- (void)setShouldCancel:(BOOL)shouldCancel;
- (BOOL)shouldCancel;
@end

@implementation Canceller
- (void)setShouldCancel:(BOOL)shouldCancel {
    _shouldCancel = shouldCancel;
}
- (BOOL)shouldCancel {
    return _shouldCancel;
}
@end

static void test(int a){
    static Canceller * canceller = nil;

    if(q){
        [canceller setShouldCancel:YES];
        [canceller release];
        dispatch_suspend(q);
        dispatch_release(q);
        q=nil;
    }
    canceller = [[Canceller alloc] init];
    q=dispatch_get_global_queue(0,0);
    dispatch_async(q,^ {
        while(![canceller shouldCancel]){NSLog(@"query %d",a);sleep(2);}
    });

}

それが役に立てば幸い。

于 2013-05-01T12:33:59.183 に答える
0

を使用できます

- (void)setSuspended:(BOOL)suspend

NSOperationQueue のメソッド? 新しい操作を追加する前に、isSuspended? でキューが中断されているかどうかを確認します。

編集 :ここでパラメーターsuspend YES の場合、キューは実行のためにキューに入れられた操作のスケジューリングを停止します。NO の場合、キューはスケジューリング操作を再開します。解説 このメソッドは、操作の実行を一時停止または再開します。キューを一時停止すると、そのキューが追加の操作を開始できなくなります。つまり、キューにある (または後でキューに追加された) まだ実行されていない操作は、キューが再開されるまで開始できません。キューを中断しても、すでに実行中の操作は停止しません。

操作は、実行が終了したときにのみキューから削除されます。ただし、実行を終了するには、まず操作を開始する必要があります。中断されたキューは新しい操作を開始しないため、現在キューに入れられていて実行されていない操作 (キャンセルされた操作を含む) は削除されません。

お役に立てば幸いです。

于 2013-05-01T12:12:55.320 に答える