2

私のアプリでは、ユーザーがアプリを閉じたとき(つまり、アプリがバックグラウンドに入ったとき)にデータをサーバーと同期しています。このプロセスには約1分かかり、データをアップロードするためにサーバーへのさまざまな呼び出しが含まれるため、バックグラウンドスレッドとして実行することを選択しています。

- (void)applicationDidEnterBackground:(UIApplication *)application {

    bgTask = [application beginBackgroundTaskWithExpirationHandler:^{
        [application endBackgroundTask:bgTask];
        bgTask = UIBackgroundTaskInvalid;
    }];

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        [asynchronousAPIController processQueueOrWaitWithIsBackgroundSync:true];

        [application endBackgroundTask:bgTask];
        bgTask = UIBackgroundTaskInvalid;
    });
}

この同期中に(つまり、最初の1分間に)ユーザーがフォアグラウンドに再入らない限り、これは正常に機能します。私が欲しいのは、バックグラウンド同期が完了した状態で終了することです。同期の途中であっても、同期を停止します。次にアプリがバックグラウンドに入ると、プロセス全体を最初から再開できます。問題ありません。

私はこれを使ってみました:

- (void)applicationWillEnterForeground:(UIApplication *)application {
    if (bgTask != UIBackgroundTaskInvalid) {
        [application endBackgroundTask:bgTask];
        bgTask = UIBackgroundTaskInvalid;
    }
}

しかし、それは同期を停止しません-それはただ進み続けます。一度開始すると、それはただ進み続けるかのように。

同期を制御しているオブジェクトがシングルトンである可能性があるのではないかと疑っています。つまり、破壊される可能性のあるクラスオブジェクトではなく、シングルトンであるため、その理由で存続している可能性があります。それは違いを生むことができますか?

それとも私は何か間違ったことをしているだけですか?

アドバイスをいただければ幸いです。

4

1 に答える 1

4

NSOperationでバックグラウンド作業を行う必要があります。NSBlockOperationを作成し、それをNSOperationQueueに追加します。このようにして、バックグラウンドスレッドが自動的に生成されます。複雑な操作の場合は、NSOperationサブクラスを作成します。NSOperationコード内で、操作が定期的にキャンセルされているかどうかを確認し(たとえば、forループ内で)、キャンセルされている場合はコードブロックを終了します(forループ内で:) if ([operation isCanceled]) break;。applicationWillEnterForegroundで、操作をキャンセルするだけです。

于 2012-10-14T13:44:21.337 に答える